1 /* Subroutines used for code generation on IBM S/390 and zSeries
2 Copyright (C) 1999, 2000, 2001 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 GNU CC.
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
29 #include "hard-reg-set.h"
31 #include "insn-config.h"
32 #include "conditions.h"
34 #include "insn-attr.h"
41 #include "basic-block.h"
42 #include "integrate.h"
45 #include "target-def.h"
49 static bool s390_assemble_integer
PARAMS ((rtx
, unsigned int, int));
50 static int s390_adjust_cost
PARAMS ((rtx
, rtx
, rtx
, int));
51 static int s390_adjust_priority
PARAMS ((rtx
, int));
53 #undef TARGET_ASM_ALIGNED_HI_OP
54 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
55 #undef TARGET_ASM_ALIGNED_DI_OP
56 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
57 #undef TARGET_ASM_INTEGER
58 #define TARGET_ASM_INTEGER s390_assemble_integer
60 #undef TARGET_ASM_FUNCTION_PROLOGUE
61 #define TARGET_ASM_FUNCTION_PROLOGUE s390_function_prologue
63 #undef TARGET_ASM_FUNCTION_EPILOGUE
64 #define TARGET_ASM_FUNCTION_EPILOGUE s390_function_epilogue
66 #undef TARGET_ASM_OPEN_PAREN
67 #define TARGET_ASM_OPEN_PAREN ""
69 #undef TARGET_ASM_CLOSE_PAREN
70 #define TARGET_ASM_CLOSE_PAREN ""
72 #undef TARGET_SCHED_ADJUST_COST
73 #define TARGET_SCHED_ADJUST_COST s390_adjust_cost
75 #undef TARGET_SCHED_ADJUST_PRIORITY
76 #define TARGET_SCHED_ADJUST_PRIORITY s390_adjust_priority
78 struct gcc_target targetm
= TARGET_INITIALIZER
;
80 extern int reload_completed
;
82 /* The alias set for prologue/epilogue register save/restore. */
83 static int s390_sr_alias_set
= 0;
85 /* Function count for creating unique internal labels in a compile unit. */
86 int s390_function_count
= 0;
88 /* Save information from a "cmpxx" operation until the branch or scc is
90 rtx s390_compare_op0
, s390_compare_op1
;
92 /* Structure used to hold the components of a S/390 memory
93 address. A legitimate address on S/390 is of the general
95 base + index + displacement
96 where any of the components is optional.
98 base and index are registers of the class ADDR_REGS,
99 displacement is an unsigned 12-bit immediate constant. */
108 /* Structure containing information for prologue and epilogue. */
113 int return_reg_saved_p
;
116 int first_restore_gpr
;
118 int arg_frame_offset
;
120 HOST_WIDE_INT frame_size
;
123 static int s390_match_ccmode_set
PARAMS ((rtx
, enum machine_mode
));
124 static int s390_branch_condition_mask
PARAMS ((rtx
));
125 static const char *s390_branch_condition_mnemonic
PARAMS ((rtx
, int));
126 static int check_mode
PARAMS ((rtx
, enum machine_mode
*));
127 static int general_s_operand
PARAMS ((rtx
, enum machine_mode
, int));
128 static int s390_decompose_address
PARAMS ((rtx
, struct s390_address
*, int));
129 static int reg_used_in_mem_p
PARAMS ((int, rtx
));
130 static int addr_generation_dependency_p
PARAMS ((rtx
, rtx
));
131 static int other_chunk
PARAMS ((int *, int, int));
132 static int far_away
PARAMS ((int, int));
133 static rtx check_and_change_labels
PARAMS ((rtx
, int *));
134 static void s390_final_chunkify
PARAMS ((int));
135 static int save_fprs_p
PARAMS ((void));
136 static int find_unused_clobbered_reg
PARAMS ((void));
137 static void s390_frame_info
PARAMS ((struct s390_frame
*));
138 static rtx save_fpr
PARAMS ((rtx
, int, int));
139 static rtx restore_fpr
PARAMS ((rtx
, int, int));
140 static int s390_function_arg_size
PARAMS ((enum machine_mode
, tree
));
143 /* Return true if SET either doesn't set the CC register, or else
144 the source and destination have matching CC modes and that
145 CC mode is at least as constrained as REQ_MODE. */
148 s390_match_ccmode_set (set
, req_mode
)
150 enum machine_mode req_mode
;
152 enum machine_mode set_mode
;
154 if (GET_CODE (set
) != SET
)
157 if (GET_CODE (SET_DEST (set
)) != REG
|| !CC_REGNO_P (REGNO (SET_DEST (set
))))
160 set_mode
= GET_MODE (SET_DEST (set
));
164 if (req_mode
!= CCSmode
)
168 if (req_mode
!= CCUmode
)
172 if (req_mode
!= CCLmode
)
176 if (req_mode
!= CCSmode
&& req_mode
!= CCUmode
&& req_mode
!= CCTmode
)
184 return (GET_MODE (SET_SRC (set
)) == set_mode
);
187 /* Return true if every SET in INSN that sets the CC register
188 has source and destination with matching CC modes and that
189 CC mode is at least as constrained as REQ_MODE. */
192 s390_match_ccmode (insn
, req_mode
)
194 enum machine_mode req_mode
;
198 if (GET_CODE (PATTERN (insn
)) == SET
)
199 return s390_match_ccmode_set (PATTERN (insn
), req_mode
);
201 if (GET_CODE (PATTERN (insn
)) == PARALLEL
)
202 for (i
= 0; i
< XVECLEN (PATTERN (insn
), 0); i
++)
204 rtx set
= XVECEXP (PATTERN (insn
), 0, i
);
205 if (GET_CODE (set
) == SET
)
206 if (!s390_match_ccmode_set (set
, req_mode
))
213 /* Given a comparison code OP (EQ, NE, etc.) and the operands
214 OP0 and OP1 of a COMPARE, return the mode to be used for the
218 s390_select_ccmode (code
, op0
, op1
)
227 if (GET_CODE (op0
) == PLUS
|| GET_CODE (op0
) == MINUS
228 || GET_CODE (op1
) == NEG
)
258 /* Return branch condition mask to implement a branch
259 specified by CODE. */
262 s390_branch_condition_mask (code
)
265 const int CC0
= 1 << 3;
266 const int CC1
= 1 << 2;
267 const int CC2
= 1 << 1;
268 const int CC3
= 1 << 0;
270 if (GET_CODE (XEXP (code
, 0)) != REG
271 || REGNO (XEXP (code
, 0)) != CC_REGNUM
272 || XEXP (code
, 1) != const0_rtx
)
275 switch (GET_MODE (XEXP (code
, 0)))
278 switch (GET_CODE (code
))
281 case NE
: return CC1
| CC2
| CC3
;
288 switch (GET_CODE (code
))
290 case EQ
: return CC0
| CC2
;
291 case NE
: return CC1
| CC3
;
292 case UNORDERED
: return CC2
| CC3
; /* carry */
293 case ORDERED
: return CC0
| CC1
; /* no carry */
300 switch (GET_CODE (code
))
303 case NE
: return CC1
| CC2
| CC3
;
304 case LTU
: return CC1
;
305 case GTU
: return CC2
;
306 case LEU
: return CC0
| CC1
;
307 case GEU
: return CC0
| CC2
;
314 switch (GET_CODE (code
))
317 case NE
: return CC1
| CC2
| CC3
;
320 case LE
: return CC0
| CC1
;
321 case GE
: return CC0
| CC2
;
322 case UNORDERED
: return CC3
;
323 case ORDERED
: return CC0
| CC1
| CC2
;
324 case UNEQ
: return CC0
| CC3
;
325 case UNLT
: return CC1
| CC3
;
326 case UNGT
: return CC2
| CC3
;
327 case UNLE
: return CC0
| CC1
| CC3
;
328 case UNGE
: return CC0
| CC2
| CC3
;
329 case LTGT
: return CC1
| CC2
;
339 /* If INV is false, return assembler mnemonic string to implement
340 a branch specified by CODE. If INV is true, return mnemonic
341 for the corresponding inverted branch. */
344 s390_branch_condition_mnemonic (code
, inv
)
348 static const char *mnemonic
[16] =
350 NULL
, "o", "h", "nle",
351 "l", "nhe", "lh", "ne",
352 "e", "nlh", "he", "nl",
353 "le", "nh", "no", NULL
356 int mask
= s390_branch_condition_mask (code
);
361 if (mask
< 1 || mask
> 14)
364 return mnemonic
[mask
];
367 /* If OP is an integer constant of mode MODE with exactly one
368 HImode subpart unequal to DEF, return the number of that
369 subpart. As a special case, all HImode subparts of OP are
370 equal to DEF, return zero. Otherwise, return -1. */
373 s390_single_hi (op
, mode
, def
)
375 enum machine_mode mode
;
378 if (GET_CODE (op
) == CONST_INT
)
380 unsigned HOST_WIDE_INT value
;
381 int n_parts
= GET_MODE_SIZE (mode
) / 2;
384 for (i
= 0; i
< n_parts
; i
++)
387 value
= (unsigned HOST_WIDE_INT
) INTVAL (op
);
391 if ((value
& 0xffff) != (unsigned)(def
& 0xffff))
400 return part
== -1 ? 0 : (n_parts
- 1 - part
);
403 else if (GET_CODE (op
) == CONST_DOUBLE
404 && GET_MODE (op
) == VOIDmode
)
406 unsigned HOST_WIDE_INT value
;
407 int n_parts
= GET_MODE_SIZE (mode
) / 2;
410 for (i
= 0; i
< n_parts
; i
++)
413 value
= (unsigned HOST_WIDE_INT
) CONST_DOUBLE_LOW (op
);
414 else if (i
== HOST_BITS_PER_WIDE_INT
/ 16)
415 value
= (unsigned HOST_WIDE_INT
) CONST_DOUBLE_HIGH (op
);
419 if ((value
& 0xffff) != (unsigned)(def
& 0xffff))
428 return part
== -1 ? 0 : (n_parts
- 1 - part
);
434 /* Extract the HImode part number PART from integer
435 constant OP of mode MODE. */
438 s390_extract_hi (op
, mode
, part
)
440 enum machine_mode mode
;
443 int n_parts
= GET_MODE_SIZE (mode
) / 2;
444 if (part
< 0 || part
>= n_parts
)
447 part
= n_parts
- 1 - part
;
449 if (GET_CODE (op
) == CONST_INT
)
451 unsigned HOST_WIDE_INT value
= (unsigned HOST_WIDE_INT
) INTVAL (op
);
452 return ((value
>> (16 * part
)) & 0xffff);
454 else if (GET_CODE (op
) == CONST_DOUBLE
455 && GET_MODE (op
) == VOIDmode
)
457 unsigned HOST_WIDE_INT value
;
458 if (part
< HOST_BITS_PER_WIDE_INT
/ 16)
459 value
= (unsigned HOST_WIDE_INT
) CONST_DOUBLE_LOW (op
);
461 value
= (unsigned HOST_WIDE_INT
) CONST_DOUBLE_HIGH (op
),
462 part
-= HOST_BITS_PER_WIDE_INT
/ 16;
464 return ((value
>> (16 * part
)) & 0xffff);
470 /* If OP is an integer constant of mode MODE with exactly one
471 QImode subpart unequal to DEF, return the number of that
472 subpart. As a special case, all QImode subparts of OP are
473 equal to DEF, return zero. Otherwise, return -1. */
476 s390_single_qi (op
, mode
, def
)
478 enum machine_mode mode
;
481 if (GET_CODE (op
) == CONST_INT
)
483 unsigned HOST_WIDE_INT value
;
484 int n_parts
= GET_MODE_SIZE (mode
);
487 for (i
= 0; i
< n_parts
; i
++)
490 value
= (unsigned HOST_WIDE_INT
) INTVAL (op
);
494 if ((value
& 0xff) != (unsigned)(def
& 0xff))
503 return part
== -1 ? 0 : (n_parts
- 1 - part
);
506 else if (GET_CODE (op
) == CONST_DOUBLE
507 && GET_MODE (op
) == VOIDmode
)
509 unsigned HOST_WIDE_INT value
;
510 int n_parts
= GET_MODE_SIZE (mode
);
513 for (i
= 0; i
< n_parts
; i
++)
516 value
= (unsigned HOST_WIDE_INT
) CONST_DOUBLE_LOW (op
);
517 else if (i
== HOST_BITS_PER_WIDE_INT
/ 8)
518 value
= (unsigned HOST_WIDE_INT
) CONST_DOUBLE_HIGH (op
);
522 if ((value
& 0xff) != (unsigned)(def
& 0xff))
531 return part
== -1 ? 0 : (n_parts
- 1 - part
);
537 /* Extract the QImode part number PART from integer
538 constant OP of mode MODE. */
541 s390_extract_qi (op
, mode
, part
)
543 enum machine_mode mode
;
546 int n_parts
= GET_MODE_SIZE (mode
);
547 if (part
< 0 || part
>= n_parts
)
550 part
= n_parts
- 1 - part
;
552 if (GET_CODE (op
) == CONST_INT
)
554 unsigned HOST_WIDE_INT value
= (unsigned HOST_WIDE_INT
) INTVAL (op
);
555 return ((value
>> (8 * part
)) & 0xff);
557 else if (GET_CODE (op
) == CONST_DOUBLE
558 && GET_MODE (op
) == VOIDmode
)
560 unsigned HOST_WIDE_INT value
;
561 if (part
< HOST_BITS_PER_WIDE_INT
/ 8)
562 value
= (unsigned HOST_WIDE_INT
) CONST_DOUBLE_LOW (op
);
564 value
= (unsigned HOST_WIDE_INT
) CONST_DOUBLE_HIGH (op
),
565 part
-= HOST_BITS_PER_WIDE_INT
/ 8;
567 return ((value
>> (8 * part
)) & 0xff);
574 /* Change optimizations to be performed, depending on the
577 LEVEL is the optimization level specified; 2 if `-O2' is
578 specified, 1 if `-O' is specified, and 0 if neither is specified.
580 SIZE is non-zero if `-Os' is specified and zero otherwise. */
583 optimization_options (level
, size
)
584 int level ATTRIBUTE_UNUSED
;
585 int size ATTRIBUTE_UNUSED
;
587 #ifdef HAVE_decrement_and_branch_on_count
588 /* When optimizing, enable use of BRCT instruction. */
590 flag_branch_on_count_reg
= 1;
597 /* Acquire a unique set number for our register saves and restores. */
598 s390_sr_alias_set
= new_alias_set ();
602 /* Map for smallest class containing reg regno. */
604 enum reg_class regclass_map
[FIRST_PSEUDO_REGISTER
] =
605 { GENERAL_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
606 ADDR_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
607 ADDR_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
608 ADDR_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
609 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
610 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
611 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
612 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
613 ADDR_REGS
, NO_REGS
, ADDR_REGS
617 /* Return true if OP a (const_int 0) operand.
618 OP is the current operation.
619 MODE is the current operation mode. */
622 const0_operand (op
, mode
)
624 enum machine_mode mode
;
626 return op
== CONST0_RTX (mode
);
629 /* Return true if the mode of operand OP matches MODE.
630 If MODE is set to VOIDmode, set it to the mode of OP. */
633 check_mode (op
, mode
)
635 enum machine_mode
*mode
;
637 if (*mode
== VOIDmode
)
638 *mode
= GET_MODE (op
);
641 if (GET_MODE (op
) != VOIDmode
&& GET_MODE (op
) != *mode
)
647 /* Return true if OP a valid operand for the LARL instruction.
648 OP is the current operation.
649 MODE is the current operation mode. */
652 larl_operand (op
, mode
)
654 enum machine_mode mode
;
656 if (! check_mode (op
, &mode
))
659 /* Allow labels and local symbols. */
660 if (GET_CODE (op
) == LABEL_REF
)
662 if (GET_CODE (op
) == SYMBOL_REF
663 && (!flag_pic
|| SYMBOL_REF_FLAG (op
)
664 || CONSTANT_POOL_ADDRESS_P (op
)))
667 /* Everything else must have a CONST, so strip it. */
668 if (GET_CODE (op
) != CONST
)
672 /* Allow adding *even* constants. */
673 if (GET_CODE (op
) == PLUS
)
675 if (GET_CODE (XEXP (op
, 1)) != CONST_INT
676 || (INTVAL (XEXP (op
, 1)) & 1) != 0)
681 /* Labels and local symbols allowed here as well. */
682 if (GET_CODE (op
) == LABEL_REF
)
684 if (GET_CODE (op
) == SYMBOL_REF
685 && (!flag_pic
|| SYMBOL_REF_FLAG (op
)
686 || CONSTANT_POOL_ADDRESS_P (op
)))
689 /* Now we must have a @GOTENT offset or @PLT stub. */
690 if (GET_CODE (op
) == UNSPEC
691 && XINT (op
, 1) == 111)
693 if (GET_CODE (op
) == UNSPEC
694 && XINT (op
, 1) == 113)
700 /* Return true if OP is a valid FP-Register.
701 OP is the current operation.
702 MODE is the current operation mode. */
705 fp_operand (op
, mode
)
707 enum machine_mode mode
;
709 register enum rtx_code code
= GET_CODE (op
);
710 if (! check_mode (op
, &mode
))
712 if (code
== REG
&& REGNO_OK_FOR_FP_P (REGNO (op
)))
718 /* Helper routine to implement s_operand and s_imm_operand.
719 OP is the current operation.
720 MODE is the current operation mode.
721 ALLOW_IMMEDIATE specifies whether immediate operands should
722 be accepted or not. */
725 general_s_operand (op
, mode
, allow_immediate
)
727 enum machine_mode mode
;
730 struct s390_address addr
;
732 /* Call general_operand first, so that we don't have to
733 check for many special cases. */
734 if (!general_operand (op
, mode
))
737 /* Just like memory_operand, allow (subreg (mem ...))
740 && GET_CODE (op
) == SUBREG
741 && GET_CODE (SUBREG_REG (op
)) == MEM
)
742 op
= SUBREG_REG (op
);
744 switch (GET_CODE (op
))
746 /* Constants that we are sure will be forced to the
747 literal pool in reload are OK as s-operand. Note
748 that we cannot call s390_preferred_reload_class here
749 because it might not be known yet at this point
750 whether the current function is a leaf or not. */
753 if (!allow_immediate
|| reload_completed
)
755 if (!legitimate_reload_constant_p (op
))
761 /* Memory operands are OK unless they already use an
764 if (GET_CODE (XEXP (op
, 0)) == ADDRESSOF
)
766 if (s390_decompose_address (XEXP (op
, 0), &addr
, FALSE
)
778 /* Return true if OP is a valid S-type operand.
779 OP is the current operation.
780 MODE is the current operation mode. */
785 enum machine_mode mode
;
787 return general_s_operand (op
, mode
, 0);
790 /* Return true if OP is a valid S-type operand or an immediate
791 operand that can be addressed as S-type operand by forcing
792 it into the literal pool.
793 OP is the current operation.
794 MODE is the current operation mode. */
797 s_imm_operand (op
, mode
)
799 enum machine_mode mode
;
801 return general_s_operand (op
, mode
, 1);
804 /* Return true if OP is a valid operand for the BRAS instruction.
805 OP is the current operation.
806 MODE is the current operation mode. */
809 bras_sym_operand (op
, mode
)
811 enum machine_mode mode ATTRIBUTE_UNUSED
;
813 register enum rtx_code code
= GET_CODE (op
);
815 /* Allow SYMBOL_REFs. */
816 if (code
== SYMBOL_REF
)
819 /* Allow @PLT stubs. */
821 && GET_CODE (XEXP (op
, 0)) == UNSPEC
822 && XINT (XEXP (op
, 0), 1) == 113)
828 /* Return true if OP is a load multiple operation. It is known to be a
829 PARALLEL and the first section will be tested.
830 OP is the current operation.
831 MODE is the current operation mode. */
834 load_multiple_operation (op
, mode
)
836 enum machine_mode mode ATTRIBUTE_UNUSED
;
838 int count
= XVECLEN (op
, 0);
839 unsigned int dest_regno
;
844 /* Perform a quick check so we don't blow up below. */
846 || GET_CODE (XVECEXP (op
, 0, 0)) != SET
847 || GET_CODE (SET_DEST (XVECEXP (op
, 0, 0))) != REG
848 || GET_CODE (SET_SRC (XVECEXP (op
, 0, 0))) != MEM
)
851 dest_regno
= REGNO (SET_DEST (XVECEXP (op
, 0, 0)));
852 src_addr
= XEXP (SET_SRC (XVECEXP (op
, 0, 0)), 0);
854 /* Check, is base, or base + displacement. */
856 if (GET_CODE (src_addr
) == REG
)
858 else if (GET_CODE (src_addr
) == PLUS
859 && GET_CODE (XEXP (src_addr
, 0)) == REG
860 && GET_CODE (XEXP (src_addr
, 1)) == CONST_INT
)
862 off
= INTVAL (XEXP (src_addr
, 1));
863 src_addr
= XEXP (src_addr
, 0);
868 if (src_addr
== frame_pointer_rtx
|| src_addr
== arg_pointer_rtx
)
871 for (i
= 1; i
< count
; i
++)
873 rtx elt
= XVECEXP (op
, 0, i
);
875 if (GET_CODE (elt
) != SET
876 || GET_CODE (SET_DEST (elt
)) != REG
877 || GET_MODE (SET_DEST (elt
)) != Pmode
878 || REGNO (SET_DEST (elt
)) != dest_regno
+ i
879 || GET_CODE (SET_SRC (elt
)) != MEM
880 || GET_MODE (SET_SRC (elt
)) != Pmode
881 || GET_CODE (XEXP (SET_SRC (elt
), 0)) != PLUS
882 || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt
), 0), 0), src_addr
)
883 || GET_CODE (XEXP (XEXP (SET_SRC (elt
), 0), 1)) != CONST_INT
884 || INTVAL (XEXP (XEXP (SET_SRC (elt
), 0), 1))
885 != off
+ i
* UNITS_PER_WORD
)
892 /* Return true if OP is a store multiple operation. It is known to be a
893 PARALLEL and the first section will be tested.
894 OP is the current operation.
895 MODE is the current operation mode. */
898 store_multiple_operation (op
, mode
)
900 enum machine_mode mode ATTRIBUTE_UNUSED
;
902 int count
= XVECLEN (op
, 0);
903 unsigned int src_regno
;
907 /* Perform a quick check so we don't blow up below. */
909 || GET_CODE (XVECEXP (op
, 0, 0)) != SET
910 || GET_CODE (SET_DEST (XVECEXP (op
, 0, 0))) != MEM
911 || GET_CODE (SET_SRC (XVECEXP (op
, 0, 0))) != REG
)
914 src_regno
= REGNO (SET_SRC (XVECEXP (op
, 0, 0)));
915 dest_addr
= XEXP (SET_DEST (XVECEXP (op
, 0, 0)), 0);
917 /* Check, is base, or base + displacement. */
919 if (GET_CODE (dest_addr
) == REG
)
921 else if (GET_CODE (dest_addr
) == PLUS
922 && GET_CODE (XEXP (dest_addr
, 0)) == REG
923 && GET_CODE (XEXP (dest_addr
, 1)) == CONST_INT
)
925 off
= INTVAL (XEXP (dest_addr
, 1));
926 dest_addr
= XEXP (dest_addr
, 0);
931 if (dest_addr
== frame_pointer_rtx
|| dest_addr
== arg_pointer_rtx
)
934 for (i
= 1; i
< count
; i
++)
936 rtx elt
= XVECEXP (op
, 0, i
);
938 if (GET_CODE (elt
) != SET
939 || GET_CODE (SET_SRC (elt
)) != REG
940 || GET_MODE (SET_SRC (elt
)) != Pmode
941 || REGNO (SET_SRC (elt
)) != src_regno
+ i
942 || GET_CODE (SET_DEST (elt
)) != MEM
943 || GET_MODE (SET_DEST (elt
)) != Pmode
944 || GET_CODE (XEXP (SET_DEST (elt
), 0)) != PLUS
945 || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt
), 0), 0), dest_addr
)
946 || GET_CODE (XEXP (XEXP (SET_DEST (elt
), 0), 1)) != CONST_INT
947 || INTVAL (XEXP (XEXP (SET_DEST (elt
), 0), 1))
948 != off
+ i
* UNITS_PER_WORD
)
955 /* Return true if OP contains a symbol reference */
958 symbolic_reference_mentioned_p (op
)
961 register const char *fmt
;
964 if (GET_CODE (op
) == SYMBOL_REF
|| GET_CODE (op
) == LABEL_REF
)
967 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
968 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
974 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
975 if (symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
)))
979 else if (fmt
[i
] == 'e' && symbolic_reference_mentioned_p (XEXP (op
, i
)))
987 /* Return true if OP is a legitimate general operand when
988 generating PIC code. It is given that flag_pic is on
989 and that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
992 legitimate_pic_operand_p (op
)
995 /* Accept all non-symbolic constants. */
996 if (!SYMBOLIC_CONST (op
))
999 /* Accept immediate LARL operands. */
1001 return larl_operand (op
, VOIDmode
);
1003 /* Reject everything else; must be handled
1004 via emit_pic_move. */
1008 /* Returns true if the constant value OP is a legitimate general operand.
1009 It is given that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
1012 legitimate_constant_p (op
)
1015 /* Accept all non-symbolic constants. */
1016 if (!SYMBOLIC_CONST (op
))
1019 /* In the PIC case, symbolic constants must *not* be
1020 forced into the literal pool. We accept them here,
1021 so that they will be handled by emit_pic_move. */
1025 /* Even in the non-PIC case, we can accept immediate
1026 LARL operands here. */
1028 return larl_operand (op
, VOIDmode
);
1030 /* All remaining non-PIC symbolic constants are
1031 forced into the literal pool. */
1035 /* Returns true if the constant value OP is a legitimate general
1036 operand during and after reload. The difference to
1037 legitimate_constant_p is that this function will not accept
1038 a constant that would need to be forced to the literal pool
1039 before it can be used as operand. */
1042 legitimate_reload_constant_p (op
)
1045 /* Accept l(g)hi operands. */
1046 if (GET_CODE (op
) == CONST_INT
1047 && CONST_OK_FOR_LETTER_P (INTVAL (op
), 'K'))
1050 /* Accept lliXX operands. */
1052 && s390_single_hi (op
, DImode
, 0) >= 0)
1055 /* Accept larl operands. */
1057 && larl_operand (op
, VOIDmode
))
1060 /* If reload is completed, and we do not already have a
1061 literal pool, and OP must be forced to the literal
1062 pool, then something must have gone wrong earlier.
1063 We *cannot* force the constant any more, because the
1064 prolog generation already decided we don't need to
1065 set up the base register. */
1066 if (reload_completed
&& !regs_ever_live
[BASE_REGISTER
])
1069 /* Everything else cannot be handled without reload. */
1073 /* Given an rtx OP being reloaded into a reg required to be in class CLASS,
1074 return the class of reg to actually use. */
1077 s390_preferred_reload_class (op
, class)
1079 enum reg_class
class;
1081 /* This can happen if a floating point constant is being
1082 reloaded into an integer register. Leave well alone. */
1083 if (GET_MODE_CLASS (GET_MODE (op
)) == MODE_FLOAT
1084 && class != FP_REGS
)
1087 switch (GET_CODE (op
))
1089 /* Constants we cannot reload must be forced into the
1090 literal pool. For constants we *could* handle directly,
1091 it might still be preferable to put them in the pool and
1092 use a memory-to-memory instruction.
1094 However, try to avoid needlessly allocating a literal
1095 pool in a routine that wouldn't otherwise need any.
1096 Heuristically, we assume that 64-bit leaf functions
1097 typically don't need a literal pool, all others do. */
1100 if (!legitimate_reload_constant_p (op
))
1103 if (TARGET_64BIT
&& current_function_is_leaf
)
1108 /* If a symbolic constant or a PLUS is reloaded,
1109 it is most likely being used as an address. */
1123 /* Decompose a RTL expression ADDR for a memory address into
1124 its components, returned in OUT. The boolean STRICT
1125 specifies whether strict register checking applies.
1126 Returns 0 if ADDR is not a valid memory address, nonzero
1127 otherwise. If OUT is NULL, don't return the components,
1128 but check for validity only.
1130 Note: Only addresses in canonical form are recognized.
1131 LEGITIMIZE_ADDRESS should convert non-canonical forms to the
1132 canonical form so that they will be recognized. */
1135 s390_decompose_address (addr
, out
, strict
)
1137 struct s390_address
*out
;
1140 rtx base
= NULL_RTX
;
1141 rtx indx
= NULL_RTX
;
1142 rtx disp
= NULL_RTX
;
1144 /* Decompose address into base + index + displacement. */
1146 if (GET_CODE (addr
) == REG
|| GET_CODE (addr
) == UNSPEC
)
1149 else if (GET_CODE (addr
) == PLUS
)
1151 rtx op0
= XEXP (addr
, 0);
1152 rtx op1
= XEXP (addr
, 1);
1153 enum rtx_code code0
= GET_CODE (op0
);
1154 enum rtx_code code1
= GET_CODE (op1
);
1156 if (code0
== REG
|| code0
== UNSPEC
)
1158 if (code1
== REG
|| code1
== UNSPEC
)
1160 indx
= op0
; /* index + base */
1166 base
= op0
; /* base + displacement */
1171 else if (code0
== PLUS
)
1173 indx
= XEXP (op0
, 0); /* index + base + disp */
1174 base
= XEXP (op0
, 1);
1185 disp
= addr
; /* displacement */
1188 /* Validate base register. */
1191 if (GET_CODE (base
) == UNSPEC
)
1193 if (XVECLEN (base
, 0) != 1 || XINT (base
, 1) != 101)
1195 base
= XVECEXP (base
, 0, 0);
1198 if (GET_CODE (base
) != REG
|| GET_MODE (base
) != Pmode
)
1201 if ((strict
&& ! REG_OK_FOR_BASE_STRICT_P (base
))
1202 || (! strict
&& ! REG_OK_FOR_BASE_NONSTRICT_P (base
)))
1206 /* Validate index register. */
1209 if (GET_CODE (indx
) == UNSPEC
)
1211 if (XVECLEN (indx
, 0) != 1 || XINT (indx
, 1) != 101)
1213 indx
= XVECEXP (indx
, 0, 0);
1216 if (GET_CODE (indx
) != REG
|| GET_MODE (indx
) != Pmode
)
1219 if ((strict
&& ! REG_OK_FOR_BASE_STRICT_P (indx
))
1220 || (! strict
&& ! REG_OK_FOR_BASE_NONSTRICT_P (indx
)))
1224 /* Validate displacement. */
1227 /* Allow integer constant in range. */
1228 if (GET_CODE (disp
) == CONST_INT
)
1230 if (INTVAL (disp
) < 0 || INTVAL (disp
) >= 4096)
1234 /* In the small-PIC case, the linker converts @GOT12
1235 offsets to possible displacements. */
1236 else if (GET_CODE (disp
) == CONST
1237 && GET_CODE (XEXP (disp
, 0)) == UNSPEC
1238 && XINT (XEXP (disp
, 0), 1) == 110)
1244 /* We can convert literal pool addresses to
1245 displacements by basing them off the base register. */
1248 /* In some cases, we can accept an additional
1249 small constant offset. Split these off here. */
1251 unsigned int offset
= 0;
1253 if (GET_CODE (disp
) == CONST
1254 && GET_CODE (XEXP (disp
, 0)) == PLUS
1255 && GET_CODE (XEXP (XEXP (disp
, 0), 1)) == CONST_INT
)
1257 offset
= INTVAL (XEXP (XEXP (disp
, 0), 1));
1258 disp
= XEXP (XEXP (disp
, 0), 0);
1261 /* Now we must have a literal pool address. */
1262 if (GET_CODE (disp
) != SYMBOL_REF
1263 || !CONSTANT_POOL_ADDRESS_P (disp
))
1266 /* In 64-bit PIC mode we cannot accept symbolic
1267 constants in the constant pool. */
1268 if (TARGET_64BIT
&& flag_pic
1269 && SYMBOLIC_CONST (get_pool_constant (disp
)))
1272 /* If we have an offset, make sure it does not
1273 exceed the size of the constant pool entry. */
1274 if (offset
&& offset
>= GET_MODE_SIZE (get_pool_mode (disp
)))
1277 /* Either base or index must be free to
1278 hold the base register. */
1282 /* Convert the address. */
1284 indx
= gen_rtx_REG (Pmode
, BASE_REGISTER
);
1286 base
= gen_rtx_REG (Pmode
, BASE_REGISTER
);
1288 disp
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, disp
), 100);
1289 disp
= gen_rtx_CONST (Pmode
, disp
);
1292 disp
= plus_constant (disp
, offset
);
1306 /* Return nonzero if ADDR is a valid memory address.
1307 STRICT specifies whether strict register checking applies. */
1310 legitimate_address_p (mode
, addr
, strict
)
1311 enum machine_mode mode ATTRIBUTE_UNUSED
;
1315 return s390_decompose_address (addr
, NULL
, strict
);
1318 /* Return 1 if OP is a valid operand for the LA instruction.
1319 In 31-bit, we need to prove that the result is used as an
1320 address, as LA performs only a 31-bit addition. */
1323 legitimate_la_operand_p (op
)
1326 struct s390_address addr
;
1327 if (!s390_decompose_address (op
, &addr
, FALSE
))
1333 /* Use of the base or stack pointer implies address. */
1335 if (addr
.base
&& GET_CODE (addr
.base
) == REG
)
1337 if (REGNO (addr
.base
) == BASE_REGISTER
1338 || REGNO (addr
.base
) == STACK_POINTER_REGNUM
1339 || REGNO (addr
.base
) == FRAME_POINTER_REGNUM
)
1343 if (addr
.indx
&& GET_CODE (addr
.indx
) == REG
)
1345 if (REGNO (addr
.indx
) == BASE_REGISTER
1346 || REGNO (addr
.indx
) == STACK_POINTER_REGNUM
1347 || REGNO (addr
.base
) == FRAME_POINTER_REGNUM
)
1354 /* Return a legitimate reference for ORIG (an address) using the
1355 register REG. If REG is 0, a new pseudo is generated.
1357 There are two types of references that must be handled:
1359 1. Global data references must load the address from the GOT, via
1360 the PIC reg. An insn is emitted to do this load, and the reg is
1363 2. Static data references, constant pool addresses, and code labels
1364 compute the address as an offset from the GOT, whose base is in
1365 the PIC reg. Static data objects have SYMBOL_REF_FLAG set to
1366 differentiate them from global data objects. The returned
1367 address is the PIC reg + an unspec constant.
1369 GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC
1370 reg also appears in the address. */
1373 legitimize_pic_address (orig
, reg
)
1381 if (GET_CODE (addr
) == LABEL_REF
1382 || (GET_CODE (addr
) == SYMBOL_REF
1383 && (SYMBOL_REF_FLAG (addr
)
1384 || CONSTANT_POOL_ADDRESS_P (addr
))))
1386 /* This is a local symbol. */
1389 /* Access local symbols PC-relative via LARL.
1390 This is the same as in the non-PIC case, so it is
1391 handled automatically ... */
1395 /* Access local symbols relative to the literal pool. */
1397 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
1399 addr
= gen_rtx_UNSPEC (SImode
, gen_rtvec (1, addr
), 100);
1400 addr
= gen_rtx_CONST (SImode
, addr
);
1401 addr
= force_const_mem (SImode
, addr
);
1402 emit_move_insn (temp
, addr
);
1404 base
= gen_rtx_REG (Pmode
, BASE_REGISTER
);
1405 base
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, base
), 101);
1406 new = gen_rtx_PLUS (Pmode
, base
, temp
);
1410 emit_move_insn (reg
, new);
1415 else if (GET_CODE (addr
) == SYMBOL_REF
)
1418 reg
= gen_reg_rtx (Pmode
);
1422 /* Assume GOT offset < 4k. This is handled the same way
1423 in both 31- and 64-bit code (@GOT12). */
1425 current_function_uses_pic_offset_table
= 1;
1427 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), 110);
1428 new = gen_rtx_CONST (Pmode
, new);
1429 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, new);
1430 new = gen_rtx_MEM (Pmode
, new);
1431 RTX_UNCHANGING_P (new) = 1;
1432 emit_move_insn (reg
, new);
1435 else if (TARGET_64BIT
)
1437 /* If the GOT offset might be >= 4k, we determine the position
1438 of the GOT entry via a PC-relative LARL (@GOTENT). */
1440 rtx temp
= gen_reg_rtx (Pmode
);
1442 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), 111);
1443 new = gen_rtx_CONST (Pmode
, new);
1444 emit_move_insn (temp
, new);
1446 new = gen_rtx_MEM (Pmode
, temp
);
1447 RTX_UNCHANGING_P (new) = 1;
1448 emit_move_insn (reg
, new);
1453 /* If the GOT offset might be >= 4k, we have to load it
1454 from the literal pool (@GOT). */
1456 rtx temp
= gen_reg_rtx (Pmode
);
1458 current_function_uses_pic_offset_table
= 1;
1460 addr
= gen_rtx_UNSPEC (SImode
, gen_rtvec (1, addr
), 112);
1461 addr
= gen_rtx_CONST (SImode
, addr
);
1462 addr
= force_const_mem (SImode
, addr
);
1463 emit_move_insn (temp
, addr
);
1465 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
1466 new = gen_rtx_MEM (Pmode
, new);
1467 RTX_UNCHANGING_P (new) = 1;
1468 emit_move_insn (reg
, new);
1474 if (GET_CODE (addr
) == CONST
)
1476 addr
= XEXP (addr
, 0);
1477 if (GET_CODE (addr
) == UNSPEC
)
1479 if (XVECLEN (addr
, 0) != 1)
1481 switch (XINT (addr
, 1))
1483 /* If someone moved an @GOT or lt-relative UNSPEC
1484 out of the literal pool, force them back in. */
1488 new = force_const_mem (SImode
, orig
);
1491 /* @GOTENT is OK as is. */
1495 /* @PLT is OK as is on 64-bit, must be converted to
1496 lt-relative PLT on 31-bit. */
1500 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
1502 addr
= XVECEXP (addr
, 0, 0);
1503 addr
= gen_rtx_UNSPEC (SImode
, gen_rtvec (1, addr
), 114);
1504 addr
= gen_rtx_CONST (SImode
, addr
);
1505 addr
= force_const_mem (SImode
, addr
);
1506 emit_move_insn (temp
, addr
);
1508 base
= gen_rtx_REG (Pmode
, BASE_REGISTER
);
1509 base
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, base
), 101);
1510 new = gen_rtx_PLUS (Pmode
, base
, temp
);
1514 emit_move_insn (reg
, new);
1520 /* Everything else cannot happen. */
1525 else if (GET_CODE (addr
) != PLUS
)
1528 if (GET_CODE (addr
) == PLUS
)
1530 rtx op0
= XEXP (addr
, 0), op1
= XEXP (addr
, 1);
1531 /* Check first to see if this is a constant offset
1532 from a local symbol reference. */
1533 if ((GET_CODE (op0
) == LABEL_REF
1534 || (GET_CODE (op0
) == SYMBOL_REF
1535 && (SYMBOL_REF_FLAG (op0
)
1536 || CONSTANT_POOL_ADDRESS_P (op0
))))
1537 && GET_CODE (op1
) == CONST_INT
)
1541 if (INTVAL (op1
) & 1)
1543 /* LARL can't handle odd offsets, so emit a
1544 pair of LARL and LA. */
1545 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
1547 if (INTVAL (op1
) < 0 || INTVAL (op1
) >= 4096)
1549 int even
= INTVAL (op1
) - 1;
1550 op0
= gen_rtx_PLUS (Pmode
, op0
, GEN_INT (even
));
1554 emit_move_insn (temp
, op0
);
1555 new = gen_rtx_PLUS (Pmode
, temp
, op1
);
1559 emit_move_insn (reg
, new);
1565 /* If the offset is even, we can just use LARL.
1566 This will happen automatically. */
1571 /* Access local symbols relative to the literal pool. */
1573 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
1575 addr
= gen_rtx_UNSPEC (SImode
, gen_rtvec (1, op0
), 100);
1576 addr
= gen_rtx_PLUS (SImode
, addr
, op1
);
1577 addr
= gen_rtx_CONST (SImode
, addr
);
1578 addr
= force_const_mem (SImode
, addr
);
1579 emit_move_insn (temp
, addr
);
1581 base
= gen_rtx_REG (Pmode
, BASE_REGISTER
);
1582 base
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, base
), 101);
1583 new = gen_rtx_PLUS (Pmode
, base
, temp
);
1587 emit_move_insn (reg
, new);
1593 /* Now, check whether it is an LT-relative symbol plus offset
1594 that was pulled out of the literal pool. Force it back in. */
1596 else if (GET_CODE (op0
) == UNSPEC
1597 && GET_CODE (op1
) == CONST_INT
)
1599 if (XVECLEN (op0
, 0) != 1)
1601 if (XINT (op0
, 1) != 100)
1604 new = force_const_mem (SImode
, orig
);
1607 /* Otherwise, compute the sum. */
1610 base
= legitimize_pic_address (XEXP (addr
, 0), reg
);
1611 new = legitimize_pic_address (XEXP (addr
, 1),
1612 base
== reg
? NULL_RTX
: reg
);
1613 if (GET_CODE (new) == CONST_INT
)
1614 new = plus_constant (base
, INTVAL (new));
1617 if (GET_CODE (new) == PLUS
&& CONSTANT_P (XEXP (new, 1)))
1619 base
= gen_rtx_PLUS (Pmode
, base
, XEXP (new, 0));
1620 new = XEXP (new, 1);
1622 new = gen_rtx_PLUS (Pmode
, base
, new);
1625 if (GET_CODE (new) == CONST
)
1626 new = XEXP (new, 0);
1627 new = force_operand (new, 0);
1634 /* Emit insns to move operands[1] into operands[0]. */
1637 emit_pic_move (operands
, mode
)
1639 enum machine_mode mode ATTRIBUTE_UNUSED
;
1641 rtx temp
= no_new_pseudos
? operands
[0] : gen_reg_rtx (Pmode
);
1643 if (GET_CODE (operands
[0]) == MEM
&& SYMBOLIC_CONST (operands
[1]))
1644 operands
[1] = force_reg (Pmode
, operands
[1]);
1646 operands
[1] = legitimize_pic_address (operands
[1], temp
);
1649 /* Try machine-dependent ways of modifying an illegitimate address X
1650 to be legitimate. If we find one, return the new, valid address.
1652 OLDX is the address as it was before break_out_memory_refs was called.
1653 In some cases it is useful to look at this to decide what needs to be done.
1655 MODE is the mode of the operand pointed to by X.
1657 When -fpic is used, special handling is needed for symbolic references.
1658 See comments by legitimize_pic_address for details. */
1661 legitimize_address (x
, oldx
, mode
)
1663 register rtx oldx ATTRIBUTE_UNUSED
;
1664 enum machine_mode mode ATTRIBUTE_UNUSED
;
1666 rtx constant_term
= const0_rtx
;
1670 if (SYMBOLIC_CONST (x
)
1671 || (GET_CODE (x
) == PLUS
1672 && (SYMBOLIC_CONST (XEXP (x
, 0))
1673 || SYMBOLIC_CONST (XEXP (x
, 1)))))
1674 x
= legitimize_pic_address (x
, 0);
1676 if (legitimate_address_p (mode
, x
, FALSE
))
1680 x
= eliminate_constant_term (x
, &constant_term
);
1682 if (GET_CODE (x
) == PLUS
)
1684 if (GET_CODE (XEXP (x
, 0)) == REG
)
1686 register rtx temp
= gen_reg_rtx (Pmode
);
1687 register rtx val
= force_operand (XEXP (x
, 1), temp
);
1689 emit_move_insn (temp
, val
);
1691 x
= gen_rtx_PLUS (Pmode
, XEXP (x
, 0), temp
);
1694 else if (GET_CODE (XEXP (x
, 1)) == REG
)
1696 register rtx temp
= gen_reg_rtx (Pmode
);
1697 register rtx val
= force_operand (XEXP (x
, 0), temp
);
1699 emit_move_insn (temp
, val
);
1701 x
= gen_rtx_PLUS (Pmode
, temp
, XEXP (x
, 1));
1705 if (constant_term
!= const0_rtx
)
1706 x
= gen_rtx_PLUS (Pmode
, x
, constant_term
);
1712 /* Output symbolic constant X in assembler syntax to
1713 stdio stream FILE. */
1716 s390_output_symbolic_const (file
, x
)
1720 switch (GET_CODE (x
))
1725 s390_output_symbolic_const (file
, XEXP (x
, 0));
1729 s390_output_symbolic_const (file
, XEXP (x
, 0));
1730 fprintf (file
, "+");
1731 s390_output_symbolic_const (file
, XEXP (x
, 1));
1735 s390_output_symbolic_const (file
, XEXP (x
, 0));
1736 fprintf (file
, "-");
1737 s390_output_symbolic_const (file
, XEXP (x
, 1));
1741 output_addr_const (file
, x
);
1746 output_addr_const (file
, x
);
1750 output_addr_const (file
, x
);
1751 if (CONSTANT_POOL_ADDRESS_P (x
) && s390_pool_count
!= 0)
1752 fprintf (file
, "_%X", s390_pool_count
);
1756 if (XVECLEN (x
, 0) != 1)
1757 output_operand_lossage ("invalid UNSPEC as operand (1)");
1758 switch (XINT (x
, 1))
1761 s390_output_symbolic_const (file
, XVECEXP (x
, 0, 0));
1762 fprintf (file
, "-.LT%X_%X",
1763 s390_function_count
, s390_pool_count
);
1766 s390_output_symbolic_const (file
, XVECEXP (x
, 0, 0));
1767 fprintf (file
, "@GOT12");
1770 s390_output_symbolic_const (file
, XVECEXP (x
, 0, 0));
1771 fprintf (file
, "@GOTENT");
1774 s390_output_symbolic_const (file
, XVECEXP (x
, 0, 0));
1775 fprintf (file
, "@GOT");
1778 s390_output_symbolic_const (file
, XVECEXP (x
, 0, 0));
1779 fprintf (file
, "@PLT");
1782 s390_output_symbolic_const (file
, XVECEXP (x
, 0, 0));
1783 fprintf (file
, "@PLT-.LT%X_%X",
1784 s390_function_count
, s390_pool_count
);
1787 output_operand_lossage ("invalid UNSPEC as operand (2)");
1793 fatal_insn ("UNKNOWN in s390_output_symbolic_const !?", x
);
1798 /* Output address operand ADDR in assembler syntax to
1799 stdio stream FILE. */
1802 print_operand_address (file
, addr
)
1806 struct s390_address ad
;
1808 if (!s390_decompose_address (addr
, &ad
, TRUE
))
1809 output_operand_lossage ("Cannot decompose address.");
1812 s390_output_symbolic_const (file
, ad
.disp
);
1814 fprintf (file
, "0");
1816 if (ad
.base
&& ad
.indx
)
1817 fprintf (file
, "(%s,%s)", reg_names
[REGNO (ad
.indx
)],
1818 reg_names
[REGNO (ad
.base
)]);
1820 fprintf (file
, "(%s)", reg_names
[REGNO (ad
.base
)]);
1823 /* Output operand X in assembler syntax to stdio stream FILE.
1824 CODE specified the format flag. The following format flags
1827 'C': print opcode suffix for branch condition.
1828 'D': print opcode suffix for inverse branch condition.
1829 'Y': print current constant pool address (pc-relative).
1830 'y': print current constant pool address (absolute).
1831 'O': print only the displacement of a memory reference.
1832 'R': print only the base register of a memory reference.
1833 'N': print the second word of a DImode operand.
1834 'M': print the second word of a TImode operand.
1836 'b': print integer X as if it's an unsigned byte.
1837 'x': print integer X as if it's an unsigned word.
1838 'h': print integer X as if it's a signed word. */
1841 print_operand (file
, x
, code
)
1849 fprintf (file
, s390_branch_condition_mnemonic (x
, FALSE
));
1853 fprintf (file
, s390_branch_condition_mnemonic (x
, TRUE
));
1857 fprintf (file
, ".LT%X_%X-.", s390_function_count
, s390_pool_count
);
1861 fprintf (file
, ".LT%X_%X", s390_function_count
, s390_pool_count
);
1866 struct s390_address ad
;
1868 if (GET_CODE (x
) != MEM
1869 || !s390_decompose_address (XEXP (x
, 0), &ad
, TRUE
)
1874 s390_output_symbolic_const (file
, ad
.disp
);
1876 fprintf (file
, "0");
1882 struct s390_address ad
;
1884 if (GET_CODE (x
) != MEM
1885 || !s390_decompose_address (XEXP (x
, 0), &ad
, TRUE
)
1890 fprintf (file
, "%s", reg_names
[REGNO (ad
.base
)]);
1892 fprintf (file
, "0");
1897 if (GET_CODE (x
) == REG
)
1898 x
= gen_rtx_REG (GET_MODE (x
), REGNO (x
) + 1);
1899 else if (GET_CODE (x
) == MEM
)
1900 x
= change_address (x
, VOIDmode
, plus_constant (XEXP (x
, 0), 4));
1906 if (GET_CODE (x
) == REG
)
1907 x
= gen_rtx_REG (GET_MODE (x
), REGNO (x
) + 1);
1908 else if (GET_CODE (x
) == MEM
)
1909 x
= change_address (x
, VOIDmode
, plus_constant (XEXP (x
, 0), 8));
1915 switch (GET_CODE (x
))
1918 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
1922 output_address (XEXP (x
, 0));
1929 s390_output_symbolic_const (file
, x
);
1934 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
) & 0xff);
1935 else if (code
== 'x')
1936 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
) & 0xffff);
1937 else if (code
== 'h')
1938 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ((INTVAL (x
) & 0xffff) ^ 0x8000) - 0x8000);
1940 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
));
1944 if (GET_MODE (x
) != VOIDmode
)
1947 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, CONST_DOUBLE_LOW (x
) & 0xff);
1948 else if (code
== 'x')
1949 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, CONST_DOUBLE_LOW (x
) & 0xffff);
1950 else if (code
== 'h')
1951 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ((CONST_DOUBLE_LOW (x
) & 0xffff) ^ 0x8000) - 0x8000);
1957 fatal_insn ("UNKNOWN in print_operand !?", x
);
1962 /* Target hook for assembling integer objects. We need to define it
1963 here to work a round a bug in some versions of GAS, which couldn't
1964 handle values smaller than INT_MIN when printed in decimal. */
1967 s390_assemble_integer (x
, size
, aligned_p
)
1972 if (size
== 8 && aligned_p
1973 && GET_CODE (x
) == CONST_INT
&& INTVAL (x
) < INT_MIN
)
1975 fputs ("\t.quad\t", asm_out_file
);
1976 fprintf (asm_out_file
, HOST_WIDE_INT_PRINT_HEX
, INTVAL (x
));
1977 putc ('\n', asm_out_file
);
1980 return default_assemble_integer (x
, size
, aligned_p
);
1984 #define DEBUG_SCHED 0
1986 /* Returns true if register REGNO is used for forming
1987 a memory address in expression X. */
1990 reg_used_in_mem_p (regno
, x
)
1994 enum rtx_code code
= GET_CODE (x
);
2000 if (refers_to_regno_p (regno
, regno
+1,
2004 else if (code
== SET
2005 && GET_CODE (SET_DEST (x
)) == PC
)
2007 if (refers_to_regno_p (regno
, regno
+1,
2012 fmt
= GET_RTX_FORMAT (code
);
2013 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
2016 && reg_used_in_mem_p (regno
, XEXP (x
, i
)))
2019 else if (fmt
[i
] == 'E')
2020 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
2021 if (reg_used_in_mem_p (regno
, XVECEXP (x
, i
, j
)))
2027 /* Returns true if expression DEP_RTX sets an address register
2028 used by instruction INSN to address memory. */
2031 addr_generation_dependency_p (dep_rtx
, insn
)
2037 if (GET_CODE (dep_rtx
) == SET
)
2039 target
= SET_DEST (dep_rtx
);
2041 if (GET_CODE (target
) == REG
)
2043 int regno
= REGNO (target
);
2045 if (get_attr_type (insn
) == TYPE_LA
)
2047 pat
= PATTERN (insn
);
2048 if (GET_CODE (pat
) == PARALLEL
)
2050 if (XVECLEN (pat
, 0) != 2)
2052 pat
= XVECEXP (pat
, 0, 0);
2054 if (GET_CODE (pat
) == SET
)
2055 return refers_to_regno_p (regno
, regno
+1, SET_SRC (pat
), 0);
2059 else if (get_attr_atype (insn
) == ATYPE_MEM
)
2060 return reg_used_in_mem_p (regno
, PATTERN (insn
));
2067 /* Return the modified cost of the dependency of instruction INSN
2068 on instruction DEP_INSN through the link LINK. COST is the
2069 default cost of that dependency.
2071 Data dependencies are all handled without delay. However, if a
2072 register is modified and subsequently used as base or index
2073 register of a memory reference, at least 4 cycles need to pass
2074 between setting and using the register to avoid pipeline stalls.
2075 An exception is the LA instruction. An address generated by LA can
2076 be used by introducing only a one cycle stall on the pipeline. */
2079 s390_adjust_cost (insn
, link
, dep_insn
, cost
)
2088 /* If the dependence is an anti-dependence, there is no cost. For an
2089 output dependence, there is sometimes a cost, but it doesn't seem
2090 worth handling those few cases. */
2092 if (REG_NOTE_KIND (link
) != 0)
2095 /* If we can't recognize the insns, we can't really do anything. */
2096 if (recog_memoized (insn
) < 0 || recog_memoized (dep_insn
) < 0)
2099 dep_rtx
= PATTERN (dep_insn
);
2101 if (GET_CODE (dep_rtx
) == SET
)
2103 if (addr_generation_dependency_p (dep_rtx
, insn
))
2105 cost
+= (get_attr_type (dep_insn
) == TYPE_LA
) ? 1 : 4;
2108 fprintf (stderr
, "\n\nAddress dependency detected: cost %d\n",
2110 debug_rtx (dep_insn
);
2115 else if (GET_CODE (dep_rtx
) == PARALLEL
)
2117 for (i
= 0; i
< XVECLEN (dep_rtx
, 0); i
++)
2119 if (addr_generation_dependency_p (XVECEXP (dep_rtx
, 0, i
),
2122 cost
+= (get_attr_type (dep_insn
) == TYPE_LA
) ? 1 : 4;
2125 fprintf (stderr
, "\n\nAddress dependency detected: cost %d\n"
2127 debug_rtx (dep_insn
);
2138 /* A C statement (sans semicolon) to update the integer scheduling priority
2139 INSN_PRIORITY (INSN). Reduce the priority to execute the INSN earlier,
2140 increase the priority to execute INSN later. Do not define this macro if
2141 you do not need to adjust the scheduling priorities of insns.
2143 A LA instruction maybe scheduled later, since the pipeline bypasses the
2144 calculated value. */
2147 s390_adjust_priority (insn
, priority
)
2148 rtx insn ATTRIBUTE_UNUSED
;
2151 if (! INSN_P (insn
))
2154 if (GET_CODE (PATTERN (insn
)) == USE
2155 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
2158 switch (get_attr_type (insn
))
2164 if (priority
>= 0 && priority
< 0x01000000)
2168 /* LM in epilogue should never be scheduled. This
2169 is due to literal access done in function body.
2170 The usage of register 13 is not mentioned explicitly,
2171 leading to scheduling 'LM' accross this instructions.
2173 priority
= 0x7fffffff;
2181 /* Pool concept for Linux 390:
2182 - Function prologue saves used register
2183 - literal pool is dumped in prologue and jump across with bras
2184 - If function has more than 4 k literals, at about every
2185 S390_CHUNK_MAX offset in the function a literal pool will be
2187 - in this case, a branch from one chunk to other chunk needs
2188 a reload of base register at the code label branched to. */
2190 /* Index of constant pool chunk that is currently being processed.
2191 Set to -1 before function output has started. */
2192 int s390_pool_count
= -1;
2194 /* First insn using the constant pool chunk that is currently being
2196 rtx s390_pool_start_insn
= NULL_RTX
;
2198 /* UID of last insn using the constant pool chunk that is currently
2200 static int pool_stop_uid
;
2202 /* Called from the ASM_OUTPUT_POOL_PROLOGUE macro to
2203 prepare for printing a literal pool chunk to stdio stream FILE.
2205 FNAME and FNDECL specify the name and type of the current function.
2206 SIZE is the size in bytes of the current literal pool. */
2209 s390_asm_output_pool_prologue (file
, fname
, fndecl
, size
)
2211 const char *fname ATTRIBUTE_UNUSED
;
2213 int size ATTRIBUTE_UNUSED
;
2216 if (s390_pool_count
>0) {
2218 * We are in an internal pool, branch over
2222 fprintf (file
, "\tlarl\t%s,.LT%X_%X\n",
2223 reg_names
[BASE_REGISTER
],
2224 s390_function_count
, s390_pool_count
);
2225 readonly_data_section ();
2226 ASM_OUTPUT_ALIGN (file
, floor_log2 (3));
2227 fprintf (file
, ".LT%X_%X:\t# Pool %d\n",
2228 s390_function_count
, s390_pool_count
, s390_pool_count
);
2231 fprintf (file
,"\t.align 4\n\tbras\t%s,0f\n.LT%X_%X:\t# Pool %d \n",
2232 reg_names
[BASE_REGISTER
],
2233 s390_function_count
, s390_pool_count
, s390_pool_count
);
2236 function_section (fndecl
);
2239 /* Return true if OTHER_ADDR is in different chunk than MY_ADDR.
2240 LTORG points to a list of all literal pools inserted
2241 into the current function. */
2244 other_chunk (ltorg
, my_addr
, other_addr
)
2251 while ((ad
= ltorg
[i
++])) {
2252 if (INSN_ADDRESSES (ad
) >= my_addr
)
2256 while ((ad
= ltorg
[j
++])) {
2257 if (INSN_ADDRESSES (ad
) > other_addr
)
2267 /* Return true if OTHER_ADDR is too far away from MY_ADDR
2268 to use a relative branch instruction. */
2271 far_away (my_addr
, other_addr
)
2275 /* In 64 bit mode we can jump +- 4GB. */
2278 if (abs (my_addr
- other_addr
) > S390_REL_MAX
)
2283 /* Go through all insns in the current function (starting
2284 at INSN), replacing branch insn if necessary. A branch
2285 needs to be modified if either the distance to the
2286 target is too far to use a relative branch, or if the
2287 target uses a different literal pool than the origin.
2288 LTORG_UIDS points to a list of all literal pool insns
2289 that have been inserted. */
2292 check_and_change_labels (insn
, ltorg_uids
)
2296 rtx temp_reg
= gen_rtx_REG (Pmode
, RETURN_REGNUM
);
2297 rtx target
, jump
, cjump
;
2298 rtx pattern
, tmp
, body
, label1
;
2301 if (GET_CODE (insn
) != JUMP_INSN
)
2304 pattern
= PATTERN (insn
);
2306 addr0
= INSN_ADDRESSES (INSN_UID (insn
));
2307 if (GET_CODE (pattern
) == SET
)
2309 body
= XEXP (pattern
, 1);
2310 if (GET_CODE (body
) == LABEL_REF
)
2312 addr1
= INSN_ADDRESSES (INSN_UID (XEXP (body
, 0)));
2314 if (other_chunk (ltorg_uids
, addr0
, addr1
))
2316 SYMBOL_REF_USED (XEXP (body
, 0)) = 1;
2318 if (far_away (addr0
, addr1
))
2322 target
= gen_rtx_UNSPEC (SImode
, gen_rtvec (1, body
), 100);
2323 target
= gen_rtx_CONST (SImode
, target
);
2324 target
= force_const_mem (SImode
, target
);
2325 jump
= gen_rtx_REG (Pmode
, BASE_REGISTER
);
2326 jump
= gen_rtx_PLUS (Pmode
, jump
, temp_reg
);
2330 target
= force_const_mem (Pmode
, body
);
2334 emit_insn_before (gen_movsi (temp_reg
, target
), insn
);
2335 tmp
= emit_jump_insn_before (gen_indirect_jump (jump
), insn
);
2337 INSN_ADDRESSES_NEW (tmp
, -1);
2341 else if (GET_CODE (body
) == IF_THEN_ELSE
)
2343 if (GET_CODE (XEXP (body
, 1)) == LABEL_REF
)
2345 addr1
= INSN_ADDRESSES (INSN_UID (XEXP (XEXP (body
, 1), 0)));
2347 if (other_chunk (ltorg_uids
, addr0
, addr1
))
2349 SYMBOL_REF_USED (XEXP (XEXP (body
, 1), 0)) = 1;
2352 if (far_away (addr0
, addr1
))
2356 target
= gen_rtx_UNSPEC (SImode
, gen_rtvec (1, XEXP (body
, 1)), 100);
2357 target
= gen_rtx_CONST (SImode
, target
);
2358 target
= force_const_mem (SImode
, target
);
2359 jump
= gen_rtx_REG (Pmode
, BASE_REGISTER
);
2360 jump
= gen_rtx_PLUS (Pmode
, jump
, temp_reg
);
2364 target
= force_const_mem (Pmode
, XEXP (body
, 1));
2368 label1
= gen_label_rtx ();
2369 cjump
= gen_rtx_LABEL_REF (VOIDmode
, label1
);
2370 cjump
= gen_rtx_IF_THEN_ELSE (VOIDmode
, XEXP (body
, 0), pc_rtx
, cjump
);
2371 cjump
= gen_rtx_SET (VOIDmode
, pc_rtx
, cjump
);
2372 emit_jump_insn_before (cjump
, insn
);
2373 emit_insn_before (gen_movsi (temp_reg
, target
), insn
);
2374 tmp
= emit_jump_insn_before (gen_indirect_jump (jump
), insn
);
2375 INSN_ADDRESSES_NEW (emit_label_before (label1
, insn
), -1);
2380 else if (GET_CODE (XEXP (body
, 2)) == LABEL_REF
)
2382 addr1
= INSN_ADDRESSES (INSN_UID (XEXP (XEXP (body
, 2), 0)));
2384 if (other_chunk (ltorg_uids
, addr0
, addr1
))
2386 SYMBOL_REF_USED (XEXP (XEXP (body
, 2), 0)) = 1;
2389 if (far_away (addr0
, addr1
))
2393 target
= gen_rtx_UNSPEC (SImode
, gen_rtvec (1, XEXP (body
, 2)), 100);
2394 target
= gen_rtx_CONST (SImode
, target
);
2395 target
= force_const_mem (SImode
, target
);
2396 jump
= gen_rtx_REG (Pmode
, BASE_REGISTER
);
2397 jump
= gen_rtx_PLUS (Pmode
, jump
, temp_reg
);
2401 target
= force_const_mem (Pmode
, XEXP (body
, 2));
2405 label1
= gen_label_rtx ();
2406 cjump
= gen_rtx_LABEL_REF (VOIDmode
, label1
);
2407 cjump
= gen_rtx_IF_THEN_ELSE (VOIDmode
, XEXP (body
, 0), cjump
, pc_rtx
);
2408 cjump
= gen_rtx_SET (VOIDmode
, pc_rtx
, cjump
);
2409 emit_jump_insn_before (cjump
, insn
);
2410 emit_insn_before (gen_movsi (temp_reg
, target
), insn
);
2411 tmp
= emit_jump_insn_before (gen_indirect_jump (jump
), insn
);
2412 INSN_ADDRESSES_NEW (emit_label_before (label1
, insn
), -1);
2419 else if (GET_CODE (pattern
) == ADDR_VEC
||
2420 GET_CODE (pattern
) == ADDR_DIFF_VEC
)
2422 int i
, diff_vec_p
= GET_CODE (pattern
) == ADDR_DIFF_VEC
;
2423 int len
= XVECLEN (pattern
, diff_vec_p
);
2425 for (i
= 0; i
< len
; i
++)
2427 addr1
= INSN_ADDRESSES (INSN_UID (XEXP (XVECEXP (pattern
, diff_vec_p
, i
), 0)));
2428 if (other_chunk (ltorg_uids
, addr0
, addr1
))
2430 SYMBOL_REF_USED (XEXP (XVECEXP (pattern
, diff_vec_p
, i
), 0)) = 1;
2437 /* Called from s390_function_prologue to make final adjustments
2438 before outputting code. CHUNKIFY specifies whether we need
2439 to use multiple literal pools (because the total size of the
2440 literals exceeds 4K). */
2443 s390_final_chunkify (chunkify
)
2446 rtx insn
, ninsn
, tmp
;
2447 int addr
, naddr
= 0, uids
;
2450 int size
= insn_current_address
;
2455 ltorg_uids
= alloca (size
/ 1024 + 1024);
2456 memset (ltorg_uids
, 0, size
/ 1024 + 1024);
2460 chunk_max
= size
* 2048 / get_pool_size ();
2461 chunk_max
= chunk_max
> S390_CHUNK_MAX
2462 ? S390_CHUNK_MAX
: chunk_max
;
2465 for (insn
=get_insns (); insn
;insn
= next_real_insn (insn
))
2467 if (GET_RTX_CLASS (GET_CODE (insn
)) != 'i')
2470 addr
= INSN_ADDRESSES (INSN_UID (insn
));
2471 if ((ninsn
= next_real_insn (insn
)))
2473 naddr
= INSN_ADDRESSES (INSN_UID (ninsn
));
2476 if (chunkify
&& (addr
/ chunk_max
!= naddr
/ chunk_max
))
2478 for (tmp
= insn
; tmp
; tmp
= NEXT_INSN (tmp
))
2480 if (GET_CODE (tmp
) == CODE_LABEL
&&
2481 GET_CODE (NEXT_INSN (tmp
)) != JUMP_INSN
)
2483 ltorg_uids
[max_ltorg
++] = INSN_UID (prev_real_insn (tmp
));
2486 if (GET_CODE (tmp
) == CALL_INSN
)
2488 ltorg_uids
[max_ltorg
++] = INSN_UID (tmp
);
2491 if (INSN_ADDRESSES (INSN_UID (tmp
)) - naddr
> S390_CHUNK_OV
)
2495 fprintf (stderr
, "s390 multiple literalpool support:\n No code label between this insn %X %X",
2496 naddr
, INSN_ADDRESSES (INSN_UID (tmp
)));
2502 warning ("no code label found");
2506 ltorg_uids
[max_ltorg
] = 0;
2507 for (insn
=get_insns (),uids
=0; insn
;insn
= next_real_insn (insn
))
2509 if (GET_RTX_CLASS (GET_CODE (insn
)) != 'i')
2511 if (INSN_UID (insn
) == ltorg_uids
[uids
])
2513 INSN_ADDRESSES_NEW (emit_insn_after (gen_ltorg (
2514 gen_rtx_CONST_INT (Pmode
, ltorg_uids
[++uids
])),
2517 if (GET_CODE (insn
) == JUMP_INSN
)
2519 insn
= check_and_change_labels (insn
, ltorg_uids
);
2524 for (insn
=get_insns (); insn
;insn
= next_insn (insn
))
2526 if (GET_CODE (insn
) == CODE_LABEL
)
2528 if (SYMBOL_REF_USED (insn
))
2530 INSN_ADDRESSES_NEW (emit_insn_after (gen_reload_base (
2531 gen_rtx_LABEL_REF (Pmode
, XEXP (insn
, 0))), insn
), -1);
2536 pool_stop_uid
= ltorg_uids
[0];
2539 /* Return true if INSN is a 'ltorg' insn. */
2542 s390_stop_dump_lit_p (insn
)
2545 rtx body
=PATTERN (insn
);
2546 if (GET_CODE (body
) == PARALLEL
2547 && GET_CODE (XVECEXP (body
, 0, 0)) == SET
2548 && GET_CODE (XVECEXP (body
, 0, 1)) == USE
2549 && GET_CODE (XEXP ((XVECEXP (body
, 0, 1)),0)) == CONST_INT
2550 && GET_CODE (SET_DEST (XVECEXP (body
, 0, 0))) == REG
2551 && REGNO (SET_DEST (XVECEXP (body
, 0, 0))) == BASE_REGISTER
2552 && SET_SRC (XVECEXP (body
, 0, 0)) == pc_rtx
) {
2559 /* Output literal pool chunk to be used for insns
2560 between insn ACT_INSN and the insn with UID STOP. */
2563 s390_dump_literal_pool (act_insn
, stop
)
2567 s390_pool_start_insn
= act_insn
;
2568 pool_stop_uid
= INTVAL (stop
);
2570 output_constant_pool (current_function_name
, current_function_decl
);
2571 function_section (current_function_decl
);
2574 /* Number of elements of current constant pool. */
2575 int s390_nr_constants
;
2577 /* Return true if floating point registers need to be saved. */
2585 for (i
=24; i
<=31; i
++)
2587 if (regs_ever_live
[i
] == 1)
2593 /* Output main constant pool to stdio stream FILE. */
2596 s390_output_constant_pool (file
)
2599 /* Output constant pool. */
2600 if (s390_nr_constants
)
2602 s390_pool_count
= 0;
2605 fprintf (file
, "\tlarl\t%s,.LT%X_%X\n", reg_names
[BASE_REGISTER
],
2606 s390_function_count
, s390_pool_count
);
2607 readonly_data_section ();
2608 ASM_OUTPUT_ALIGN (file
, floor_log2 (3));
2612 fprintf (file
, "\tbras\t%s,.LTN%X_%X\n", reg_names
[BASE_REGISTER
],
2613 s390_function_count
, s390_pool_count
);
2615 fprintf (file
, ".LT%X_%X:\n", s390_function_count
, s390_pool_count
);
2616 output_constant_pool (current_function_name
, current_function_decl
);
2617 fprintf (file
, ".LTN%X_%X:\n", s390_function_count
,
2620 function_section (current_function_decl
);
2624 /* Find first call clobbered register unsused in a function.
2625 This could be used as base register in a leaf function
2626 or for holding the return address before epilogue. */
2629 find_unused_clobbered_reg ()
2632 for (i
= 0; i
< 6; i
++)
2633 if (!regs_ever_live
[i
])
2638 /* Fill FRAME with info about frame of current function. */
2641 s390_frame_info (frame
)
2642 struct s390_frame
*frame
;
2645 HOST_WIDE_INT fsize
= get_frame_size ();
2647 if (fsize
> 0x7fff0000)
2648 fatal_error ("Total size of local variables exceeds architecture limit.");
2650 /* fprs 8 - 15 are caller saved for 64 Bit ABI. */
2651 frame
->save_fprs_p
= save_fprs_p ();
2653 frame
->frame_size
= fsize
+ frame
->save_fprs_p
* 64;
2655 /* Does function need to setup frame and save area. */
2657 if (! current_function_is_leaf
2658 || frame
->frame_size
> 0
2659 || current_function_calls_alloca
2660 || current_function_stdarg
2661 || current_function_varargs
)
2662 frame
->frame_size
+= STARTING_FRAME_OFFSET
;
2664 /* If we need to allocate a frame, the stack pointer is changed. */
2666 if (frame
->frame_size
> 0)
2667 regs_ever_live
[STACK_POINTER_REGNUM
] = 1;
2669 /* If there is (possibly) any pool entry, we need to
2670 load base register. */
2672 if (get_pool_size ()
2673 || !CONST_OK_FOR_LETTER_P (frame
->frame_size
, 'K')
2674 || (!TARGET_64BIT
&& current_function_uses_pic_offset_table
))
2675 regs_ever_live
[BASE_REGISTER
] = 1;
2677 /* If we need the GOT pointer, remember to save/restore it. */
2679 if (current_function_uses_pic_offset_table
)
2680 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2682 /* Frame pointer needed. */
2684 frame
->frame_pointer_p
= frame_pointer_needed
;
2686 /* Find first and last gpr to be saved. */
2688 for (i
= 6; i
< 16; i
++)
2689 if (regs_ever_live
[i
])
2692 for (j
= 15; j
> i
; j
--)
2693 if (regs_ever_live
[j
])
2698 /* Nothing to save / restore. */
2699 frame
->first_save_gpr
= -1;
2700 frame
->first_restore_gpr
= -1;
2701 frame
->last_save_gpr
= -1;
2702 frame
->return_reg_saved_p
= 0;
2706 /* Save / Restore from gpr i to j. */
2707 frame
->first_save_gpr
= i
;
2708 frame
->first_restore_gpr
= i
;
2709 frame
->last_save_gpr
= j
;
2710 frame
->return_reg_saved_p
= (j
>= RETURN_REGNUM
&& i
<= RETURN_REGNUM
);
2713 if (current_function_stdarg
|| current_function_varargs
)
2715 /* Varargs function need to save from gpr 2 to gpr 15. */
2716 frame
->first_save_gpr
= 2;
2720 /* Return offset between argument pointer and frame pointer
2721 initially after prologue. */
2724 s390_arg_frame_offset ()
2726 struct s390_frame frame
;
2728 /* Compute frame_info. */
2730 s390_frame_info (&frame
);
2732 return frame
.frame_size
+ STACK_POINTER_OFFSET
;
2735 /* Emit insn to save fpr REGNUM at offset OFFSET relative
2736 to register BASE. Return generated insn. */
2739 save_fpr (base
, offset
, regnum
)
2745 addr
= gen_rtx_MEM (DFmode
, plus_constant (base
, offset
));
2746 set_mem_alias_set (addr
, s390_sr_alias_set
);
2748 return emit_move_insn (addr
, gen_rtx_REG (DFmode
, regnum
));
2751 /* Emit insn to restore fpr REGNUM from offset OFFSET relative
2752 to register BASE. Return generated insn. */
2755 restore_fpr (base
, offset
, regnum
)
2761 addr
= gen_rtx_MEM (DFmode
, plus_constant (base
, offset
));
2762 set_mem_alias_set (addr
, s390_sr_alias_set
);
2764 return emit_move_insn (gen_rtx_REG (DFmode
, regnum
), addr
);
2767 /* Output the function prologue assembly code to the
2768 stdio stream FILE. The local frame size is passed
2772 s390_function_prologue (file
, lsize
)
2773 FILE *file ATTRIBUTE_UNUSED
;
2774 HOST_WIDE_INT lsize ATTRIBUTE_UNUSED
;
2776 if (get_pool_size () > S390_POOL_MAX
)
2777 s390_final_chunkify (1);
2779 s390_final_chunkify (0);
2782 /* Output the function epilogue assembly code to the
2783 stdio stream FILE. The local frame size is passed
2787 s390_function_epilogue (file
, lsize
)
2788 FILE *file ATTRIBUTE_UNUSED
;
2789 HOST_WIDE_INT lsize ATTRIBUTE_UNUSED
;
2791 current_function_uses_pic_offset_table
= 0;
2792 s390_pool_start_insn
= NULL_RTX
;
2793 s390_pool_count
= -1;
2794 s390_function_count
++;
2797 /* Expand the prologue into a bunch of separate insns. */
2800 s390_emit_prologue ()
2802 struct s390_frame frame
;
2807 /* Compute frame_info. */
2809 s390_frame_info (&frame
);
2811 /* Choose best register to use for temp use within prologue. */
2813 if (frame
.return_reg_saved_p
2814 && !has_hard_reg_initial_val (Pmode
, RETURN_REGNUM
))
2815 temp_reg
= gen_rtx_REG (Pmode
, RETURN_REGNUM
);
2817 temp_reg
= gen_rtx_REG (Pmode
, 1);
2819 /* Save call saved gprs. */
2821 if (frame
.first_save_gpr
!= -1)
2823 addr
= plus_constant (stack_pointer_rtx
,
2824 frame
.first_save_gpr
* UNITS_PER_WORD
);
2825 addr
= gen_rtx_MEM (Pmode
, addr
);
2826 set_mem_alias_set (addr
, s390_sr_alias_set
);
2828 if (frame
.first_save_gpr
!= frame
.last_save_gpr
)
2830 insn
= emit_insn (gen_store_multiple (addr
,
2831 gen_rtx_REG (Pmode
, frame
.first_save_gpr
),
2832 GEN_INT (frame
.last_save_gpr
2833 - frame
.first_save_gpr
+ 1)));
2835 /* Set RTX_FRAME_RELATED_P for all sets within store multiple. */
2837 limit
= XVECLEN (PATTERN (insn
), 0);
2839 for (i
= 0; i
< limit
; i
++)
2841 rtx x
= XVECEXP (PATTERN (insn
), 0, i
);
2843 if (GET_CODE (x
) == SET
)
2844 RTX_FRAME_RELATED_P (x
) = 1;
2849 insn
= emit_move_insn (addr
,
2850 gen_rtx_REG (Pmode
, frame
.first_save_gpr
));
2852 RTX_FRAME_RELATED_P (insn
) = 1;
2855 /* Dump constant pool and set constant pool register (13). */
2857 insn
= emit_insn (gen_lit ());
2859 /* Save fprs for variable args. */
2861 if (current_function_stdarg
|| current_function_varargs
)
2863 /* Save fpr 0 and 2. */
2865 save_fpr (stack_pointer_rtx
, STACK_POINTER_OFFSET
- 32, 16);
2866 save_fpr (stack_pointer_rtx
, STACK_POINTER_OFFSET
- 24, 17);
2870 /* Save fpr 4 and 6. */
2872 save_fpr (stack_pointer_rtx
, STACK_POINTER_OFFSET
- 16, 18);
2873 save_fpr (stack_pointer_rtx
, STACK_POINTER_OFFSET
- 8, 19);
2877 /* Save fprs 4 and 6 if used (31 bit ABI). */
2881 /* Save fpr 4 and 6. */
2882 if (regs_ever_live
[18])
2884 insn
= save_fpr (stack_pointer_rtx
, STACK_POINTER_OFFSET
- 16, 18);
2885 RTX_FRAME_RELATED_P (insn
) = 1;
2887 if (regs_ever_live
[19])
2889 insn
= save_fpr (stack_pointer_rtx
, STACK_POINTER_OFFSET
- 8, 19);
2890 RTX_FRAME_RELATED_P (insn
) = 1;
2894 /* Decrement stack pointer. */
2896 if (frame
.frame_size
> 0)
2898 rtx frame_off
= GEN_INT (-frame
.frame_size
);
2900 /* Save incoming stack pointer into temp reg. */
2902 if (TARGET_BACKCHAIN
|| frame
.save_fprs_p
)
2904 insn
= emit_insn (gen_move_insn (temp_reg
, stack_pointer_rtx
));
2907 /* Substract frame size from stack pointer. */
2909 frame_off
= GEN_INT (-frame
.frame_size
);
2910 if (!CONST_OK_FOR_LETTER_P (-frame
.frame_size
, 'K'))
2911 frame_off
= force_const_mem (Pmode
, frame_off
);
2913 insn
= emit_insn (gen_add2_insn (stack_pointer_rtx
, frame_off
));
2914 RTX_FRAME_RELATED_P (insn
) = 1;
2916 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
2917 gen_rtx_SET (VOIDmode
, stack_pointer_rtx
,
2918 gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
2919 GEN_INT (-frame
.frame_size
))),
2922 /* Set backchain. */
2924 if (TARGET_BACKCHAIN
)
2926 addr
= gen_rtx_MEM (Pmode
, stack_pointer_rtx
);
2927 set_mem_alias_set (addr
, s390_sr_alias_set
);
2928 insn
= emit_insn (gen_move_insn (addr
, temp_reg
));
2932 /* Save fprs 8 - 15 (64 bit ABI). */
2934 if (frame
.save_fprs_p
)
2936 insn
= emit_insn (gen_add2_insn (temp_reg
, GEN_INT(-64)));
2938 for (i
= 24; i
< 32; i
++)
2939 if (regs_ever_live
[i
])
2941 rtx addr
= plus_constant (stack_pointer_rtx
,
2942 frame
.frame_size
- 64 + (i
-24)*8);
2944 insn
= save_fpr (temp_reg
, (i
-24)*8, i
);
2945 RTX_FRAME_RELATED_P (insn
) = 1;
2947 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
2948 gen_rtx_SET (VOIDmode
,
2949 gen_rtx_MEM (DFmode
, addr
),
2950 gen_rtx_REG (DFmode
, i
)),
2955 /* Set frame pointer, if needed. */
2957 if (frame
.frame_pointer_p
)
2959 insn
= emit_move_insn (hard_frame_pointer_rtx
, stack_pointer_rtx
);
2960 RTX_FRAME_RELATED_P (insn
) = 1;
2963 /* Set up got pointer, if needed. */
2965 if (current_function_uses_pic_offset_table
)
2967 rtx got_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "_GLOBAL_OFFSET_TABLE_");
2968 SYMBOL_REF_FLAG (got_symbol
) = 1;
2972 insn
= emit_insn (gen_movdi (pic_offset_table_rtx
,
2975 /* It can happen that the GOT pointer isn't really needed ... */
2976 REG_NOTES(insn
) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD
, NULL_RTX
,
2981 got_symbol
= gen_rtx_UNSPEC (VOIDmode
,
2982 gen_rtvec (1, got_symbol
), 100);
2983 got_symbol
= gen_rtx_CONST (VOIDmode
, got_symbol
);
2984 got_symbol
= force_const_mem (Pmode
, got_symbol
);
2985 insn
= emit_move_insn (pic_offset_table_rtx
,
2987 insn
= emit_insn (gen_add2_insn (pic_offset_table_rtx
,
2988 gen_rtx_REG (Pmode
, BASE_REGISTER
)));
2990 /* We need the GOT pointer even if we don't know it ... */
2991 emit_insn (gen_rtx_USE (VOIDmode
, pic_offset_table_rtx
));
2996 /* Expand the epilogue into a bunch of separate insns. */
2999 s390_emit_epilogue ()
3001 struct s390_frame frame
;
3002 rtx frame_pointer
, return_reg
;
3003 int area_bottom
, area_top
, offset
;
3006 /* Compute frame_info. */
3008 s390_frame_info (&frame
);
3010 /* Check whether to use frame or stack pointer for restore. */
3012 frame_pointer
= frame
.frame_pointer_p
?
3013 hard_frame_pointer_rtx
: stack_pointer_rtx
;
3015 /* Compute which parts of the save area we need to access. */
3017 if (frame
.first_restore_gpr
!= -1)
3019 area_bottom
= frame
.first_restore_gpr
* UNITS_PER_WORD
;
3020 area_top
= (frame
.last_save_gpr
+ 1) * UNITS_PER_WORD
;
3024 area_bottom
= INT_MAX
;
3030 if (frame
.save_fprs_p
)
3032 if (area_bottom
> -64)
3040 if (regs_ever_live
[18])
3042 if (area_bottom
> STACK_POINTER_OFFSET
- 16)
3043 area_bottom
= STACK_POINTER_OFFSET
- 16;
3044 if (area_top
< STACK_POINTER_OFFSET
- 8)
3045 area_top
= STACK_POINTER_OFFSET
- 8;
3047 if (regs_ever_live
[19])
3049 if (area_bottom
> STACK_POINTER_OFFSET
- 8)
3050 area_bottom
= STACK_POINTER_OFFSET
- 8;
3051 if (area_top
< STACK_POINTER_OFFSET
)
3052 area_top
= STACK_POINTER_OFFSET
;
3056 /* Check whether we can access the register save area.
3057 If not, increment the frame pointer as required. */
3059 if (area_top
<= area_bottom
)
3061 /* Nothing to restore. */
3063 else if (frame
.frame_size
+ area_bottom
>= 0
3064 && frame
.frame_size
+ area_top
<= 4096)
3066 /* Area is in range. */
3067 offset
= frame
.frame_size
;
3071 rtx insn
, frame_off
;
3073 offset
= area_bottom
< 0 ? -area_bottom
: 0;
3074 frame_off
= GEN_INT (frame
.frame_size
- offset
);
3076 if (!CONST_OK_FOR_LETTER_P (INTVAL (frame_off
), 'K'))
3077 frame_off
= force_const_mem (Pmode
, frame_off
);
3079 insn
= emit_insn (gen_add2_insn (frame_pointer
, frame_off
));
3080 RTX_FRAME_RELATED_P (insn
) = 1;
3083 /* Restore call saved fprs. */
3089 if (frame
.save_fprs_p
)
3090 for (i
= 24; i
< 32; i
++)
3091 if (regs_ever_live
[i
])
3092 restore_fpr (frame_pointer
,
3093 offset
- 64 + (i
-24) * 8, i
);
3097 if (regs_ever_live
[18])
3098 restore_fpr (frame_pointer
, offset
+ STACK_POINTER_OFFSET
- 16, 18);
3099 if (regs_ever_live
[19])
3100 restore_fpr (frame_pointer
, offset
+ STACK_POINTER_OFFSET
- 8, 19);
3103 /* Return register. */
3105 return_reg
= gen_rtx_REG (Pmode
, RETURN_REGNUM
);
3107 /* Restore call saved gprs. */
3109 if (frame
.first_restore_gpr
!= -1)
3113 /* Fetch return address from stack before load multiple,
3114 this will do good for scheduling. */
3116 if (frame
.last_save_gpr
>= RETURN_REGNUM
3117 && frame
.first_restore_gpr
< RETURN_REGNUM
)
3119 int return_regnum
= find_unused_clobbered_reg();
3122 return_reg
= gen_rtx_REG (Pmode
, return_regnum
);
3124 addr
= plus_constant (frame_pointer
,
3125 offset
+ RETURN_REGNUM
* UNITS_PER_WORD
);
3126 addr
= gen_rtx_MEM (Pmode
, addr
);
3127 set_mem_alias_set (addr
, s390_sr_alias_set
);
3128 emit_move_insn (return_reg
, addr
);
3131 /* ??? As references to the base register are not made
3132 explicit in insn RTX code, we have to add a barrier here
3133 to prevent incorrect scheduling. */
3135 emit_insn (gen_blockage());
3137 addr
= plus_constant (frame_pointer
,
3138 offset
+ frame
.first_restore_gpr
* UNITS_PER_WORD
);
3139 addr
= gen_rtx_MEM (Pmode
, addr
);
3140 set_mem_alias_set (addr
, s390_sr_alias_set
);
3142 if (frame
.first_restore_gpr
!= frame
.last_save_gpr
)
3144 emit_insn (gen_load_multiple (
3145 gen_rtx_REG (Pmode
, frame
.first_restore_gpr
),
3147 GEN_INT (frame
.last_save_gpr
- frame
.first_restore_gpr
+ 1)));
3151 emit_move_insn (gen_rtx_REG (Pmode
, frame
.first_restore_gpr
),
3156 /* Return to caller. */
3158 p
= rtvec_alloc (2);
3160 RTVEC_ELT (p
, 0) = gen_rtx_RETURN (VOIDmode
);
3161 RTVEC_ELT (p
, 1) = gen_rtx_USE (VOIDmode
, return_reg
);
3162 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
3166 /* Return the size in bytes of a function argument of
3167 type TYPE and/or mode MODE. At least one of TYPE or
3168 MODE must be specified. */
3171 s390_function_arg_size (mode
, type
)
3172 enum machine_mode mode
;
3176 return int_size_in_bytes (type
);
3178 /* No type info available for some library calls ... */
3179 if (mode
!= BLKmode
)
3180 return GET_MODE_SIZE (mode
);
3182 /* If we have neither type nor mode, abort */
3186 /* Return 1 if a function argument of type TYPE and mode MODE
3187 is to be passed by reference. The ABI specifies that only
3188 structures of size 1, 2, 4, or 8 bytes are passed by value,
3189 all other structures (and complex numbers) are passed by
3193 s390_function_arg_pass_by_reference (mode
, type
)
3194 enum machine_mode mode
;
3197 int size
= s390_function_arg_size (mode
, type
);
3201 if (AGGREGATE_TYPE_P (type
) &&
3202 size
!= 1 && size
!= 2 && size
!= 4 && size
!= 8)
3205 if (TREE_CODE (type
) == COMPLEX_TYPE
)
3212 /* Update the data in CUM to advance over an argument of mode MODE and
3213 data type TYPE. (TYPE is null for libcalls where that information
3214 may not be available.). The boolean NAMED specifies whether the
3215 argument is a named argument (as opposed to an unnamed argument
3216 matching an ellipsis). */
3219 s390_function_arg_advance (cum
, mode
, type
, named
)
3220 CUMULATIVE_ARGS
*cum
;
3221 enum machine_mode mode
;
3223 int named ATTRIBUTE_UNUSED
;
3225 if (! TARGET_SOFT_FLOAT
&& (mode
== DFmode
|| mode
== SFmode
))
3229 else if (s390_function_arg_pass_by_reference (mode
, type
))
3235 int size
= s390_function_arg_size (mode
, type
);
3236 cum
->gprs
+= ((size
+ UNITS_PER_WORD
-1) / UNITS_PER_WORD
);
3240 /* Define where to put the arguments to a function.
3241 Value is zero to push the argument on the stack,
3242 or a hard register in which to store the argument.
3244 MODE is the argument's machine mode.
3245 TYPE is the data type of the argument (as a tree).
3246 This is null for libcalls where that information may
3248 CUM is a variable of type CUMULATIVE_ARGS which gives info about
3249 the preceding args and about the function being called.
3250 NAMED is nonzero if this argument is a named parameter
3251 (otherwise it is an extra parameter matching an ellipsis).
3253 On S/390, we use general purpose registers 2 through 6 to
3254 pass integer, pointer, and certain structure arguments, and
3255 floating point registers 0 and 2 (0, 2, 4, and 6 on 64-bit)
3256 to pass floating point arguments. All remaining arguments
3257 are pushed to the stack. */
3260 s390_function_arg (cum
, mode
, type
, named
)
3261 CUMULATIVE_ARGS
*cum
;
3262 enum machine_mode mode
;
3264 int named ATTRIBUTE_UNUSED
;
3266 if (s390_function_arg_pass_by_reference (mode
, type
))
3269 if (! TARGET_SOFT_FLOAT
&& (mode
== DFmode
|| mode
== SFmode
))
3271 if (cum
->fprs
+ 1 > (TARGET_64BIT
? 4 : 2))
3274 return gen_rtx (REG
, mode
, cum
->fprs
+ 16);
3278 int size
= s390_function_arg_size (mode
, type
);
3279 int n_gprs
= (size
+ UNITS_PER_WORD
-1) / UNITS_PER_WORD
;
3281 if (cum
->gprs
+ n_gprs
> 5)
3284 return gen_rtx (REG
, mode
, cum
->gprs
+ 2);
3289 /* Create and return the va_list datatype.
3291 On S/390, va_list is an array type equivalent to
3293 typedef struct __va_list_tag
3297 void *__overflow_arg_area;
3298 void *__reg_save_area;
3302 where __gpr and __fpr hold the number of general purpose
3303 or floating point arguments used up to now, respectively,
3304 __overflow_arg_area points to the stack location of the
3305 next argument passed on the stack, and __reg_save_area
3306 always points to the start of the register area in the
3307 call frame of the current function. The function prologue
3308 saves all registers used for argument passing into this
3309 area if the function uses variable arguments. */
3312 s390_build_va_list ()
3314 tree f_gpr
, f_fpr
, f_ovf
, f_sav
, record
, type_decl
;
3316 record
= make_lang_type (RECORD_TYPE
);
3319 build_decl (TYPE_DECL
, get_identifier ("__va_list_tag"), record
);
3321 f_gpr
= build_decl (FIELD_DECL
, get_identifier ("__gpr"),
3322 long_integer_type_node
);
3323 f_fpr
= build_decl (FIELD_DECL
, get_identifier ("__fpr"),
3324 long_integer_type_node
);
3325 f_ovf
= build_decl (FIELD_DECL
, get_identifier ("__overflow_arg_area"),
3327 f_sav
= build_decl (FIELD_DECL
, get_identifier ("__reg_save_area"),
3330 DECL_FIELD_CONTEXT (f_gpr
) = record
;
3331 DECL_FIELD_CONTEXT (f_fpr
) = record
;
3332 DECL_FIELD_CONTEXT (f_ovf
) = record
;
3333 DECL_FIELD_CONTEXT (f_sav
) = record
;
3335 TREE_CHAIN (record
) = type_decl
;
3336 TYPE_NAME (record
) = type_decl
;
3337 TYPE_FIELDS (record
) = f_gpr
;
3338 TREE_CHAIN (f_gpr
) = f_fpr
;
3339 TREE_CHAIN (f_fpr
) = f_ovf
;
3340 TREE_CHAIN (f_ovf
) = f_sav
;
3342 layout_type (record
);
3344 /* The correct type is an array type of one element. */
3345 return build_array_type (record
, build_index_type (size_zero_node
));
3348 /* Implement va_start by filling the va_list structure VALIST.
3349 STDARG_P is true if implementing __builtin_stdarg_va_start,
3350 false if implementing __builtin_varargs_va_start. NEXTARG
3351 points to the first anonymous stack argument.
3353 The following global variables are used to initialize
3354 the va_list structure:
3356 current_function_args_info:
3357 holds number of gprs and fprs used for named arguments.
3358 current_function_arg_offset_rtx:
3359 holds the offset of the first anonymous stack argument
3360 (relative to the virtual arg pointer). */
3363 s390_va_start (stdarg_p
, valist
, nextarg
)
3366 rtx nextarg ATTRIBUTE_UNUSED
;
3368 HOST_WIDE_INT n_gpr
, n_fpr
;
3370 tree f_gpr
, f_fpr
, f_ovf
, f_sav
;
3371 tree gpr
, fpr
, ovf
, sav
, t
;
3373 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
3374 f_fpr
= TREE_CHAIN (f_gpr
);
3375 f_ovf
= TREE_CHAIN (f_fpr
);
3376 f_sav
= TREE_CHAIN (f_ovf
);
3378 valist
= build1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (valist
)), valist
);
3379 gpr
= build (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
);
3380 fpr
= build (COMPONENT_REF
, TREE_TYPE (f_fpr
), valist
, f_fpr
);
3381 ovf
= build (COMPONENT_REF
, TREE_TYPE (f_ovf
), valist
, f_ovf
);
3382 sav
= build (COMPONENT_REF
, TREE_TYPE (f_sav
), valist
, f_sav
);
3384 /* Count number of gp and fp argument registers used. */
3386 n_gpr
= current_function_args_info
.gprs
;
3387 n_fpr
= current_function_args_info
.fprs
;
3389 t
= build (MODIFY_EXPR
, TREE_TYPE (gpr
), gpr
, build_int_2 (n_gpr
, 0));
3390 TREE_SIDE_EFFECTS (t
) = 1;
3391 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3393 t
= build (MODIFY_EXPR
, TREE_TYPE (fpr
), fpr
, build_int_2 (n_fpr
, 0));
3394 TREE_SIDE_EFFECTS (t
) = 1;
3395 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3397 /* Find the overflow area. */
3398 t
= make_tree (TREE_TYPE (ovf
), virtual_incoming_args_rtx
);
3400 off
= INTVAL (current_function_arg_offset_rtx
);
3401 off
= off
< 0 ? 0 : off
;
3403 off
= off
> 0 ? off
- UNITS_PER_WORD
: off
;
3404 if (TARGET_DEBUG_ARG
)
3405 fprintf (stderr
, "va_start: n_gpr = %d, n_fpr = %d off %d\n",
3406 (int)n_gpr
, (int)n_fpr
, off
);
3408 t
= build (PLUS_EXPR
, TREE_TYPE (ovf
), t
, build_int_2 (off
, 0));
3410 t
= build (MODIFY_EXPR
, TREE_TYPE (ovf
), ovf
, t
);
3411 TREE_SIDE_EFFECTS (t
) = 1;
3412 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3414 /* Find the register save area. */
3415 t
= make_tree (TREE_TYPE (sav
), virtual_incoming_args_rtx
);
3416 t
= build (PLUS_EXPR
, TREE_TYPE (sav
), t
,
3417 build_int_2 (-STACK_POINTER_OFFSET
, -1));
3418 t
= build (MODIFY_EXPR
, TREE_TYPE (sav
), sav
, t
);
3419 TREE_SIDE_EFFECTS (t
) = 1;
3420 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3423 /* Implement va_arg by updating the va_list structure
3424 VALIST as required to retrieve an argument of type
3425 TYPE, and returning that argument.
3427 Generates code equivalent to:
3429 if (integral value) {
3430 if (size <= 4 && args.gpr < 5 ||
3431 size > 4 && args.gpr < 4 )
3432 ret = args.reg_save_area[args.gpr+8]
3434 ret = *args.overflow_arg_area++;
3435 } else if (float value) {
3437 ret = args.reg_save_area[args.fpr+64]
3439 ret = *args.overflow_arg_area++;
3440 } else if (aggregate value) {
3442 ret = *args.reg_save_area[args.gpr]
3444 ret = **args.overflow_arg_area++;
3448 s390_va_arg (valist
, type
)
3452 tree f_gpr
, f_fpr
, f_ovf
, f_sav
;
3453 tree gpr
, fpr
, ovf
, sav
, reg
, t
, u
;
3454 int indirect_p
, size
, n_reg
, sav_ofs
, sav_scale
, max_reg
;
3455 rtx lab_false
, lab_over
, addr_rtx
, r
;
3457 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
3458 f_fpr
= TREE_CHAIN (f_gpr
);
3459 f_ovf
= TREE_CHAIN (f_fpr
);
3460 f_sav
= TREE_CHAIN (f_ovf
);
3462 valist
= build1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (valist
)), valist
);
3463 gpr
= build (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
);
3464 fpr
= build (COMPONENT_REF
, TREE_TYPE (f_fpr
), valist
, f_fpr
);
3465 ovf
= build (COMPONENT_REF
, TREE_TYPE (f_ovf
), valist
, f_ovf
);
3466 sav
= build (COMPONENT_REF
, TREE_TYPE (f_sav
), valist
, f_sav
);
3468 size
= int_size_in_bytes (type
);
3470 if (s390_function_arg_pass_by_reference (TYPE_MODE (type
), type
))
3472 if (TARGET_DEBUG_ARG
)
3474 fprintf (stderr
, "va_arg: aggregate type");
3478 /* Aggregates are passed by reference. */
3482 sav_ofs
= 2 * UNITS_PER_WORD
;
3483 sav_scale
= UNITS_PER_WORD
;
3484 size
= UNITS_PER_WORD
;
3487 else if (FLOAT_TYPE_P (type
) && ! TARGET_SOFT_FLOAT
)
3489 if (TARGET_DEBUG_ARG
)
3491 fprintf (stderr
, "va_arg: float type");
3495 /* FP args go in FP registers, if present. */
3499 sav_ofs
= 16 * UNITS_PER_WORD
;
3501 /* TARGET_64BIT has up to 4 parameter in fprs */
3502 max_reg
= TARGET_64BIT
? 3 : 1;
3506 if (TARGET_DEBUG_ARG
)
3508 fprintf (stderr
, "va_arg: other type");
3512 /* Otherwise into GP registers. */
3515 n_reg
= (size
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
3516 sav_ofs
= 2 * UNITS_PER_WORD
;
3518 sav_ofs
+= TYPE_MODE (type
) == SImode
? 4 :
3519 TYPE_MODE (type
) == HImode
? 6 :
3520 TYPE_MODE (type
) == QImode
? 7 : 0;
3522 sav_ofs
+= TYPE_MODE (type
) == HImode
? 2 :
3523 TYPE_MODE (type
) == QImode
? 3 : 0;
3525 sav_scale
= UNITS_PER_WORD
;
3532 /* Pull the value out of the saved registers ... */
3534 lab_false
= gen_label_rtx ();
3535 lab_over
= gen_label_rtx ();
3536 addr_rtx
= gen_reg_rtx (Pmode
);
3538 emit_cmp_and_jump_insns (expand_expr (reg
, NULL_RTX
, Pmode
, EXPAND_NORMAL
),
3540 GT
, const1_rtx
, Pmode
, 0, lab_false
);
3543 t
= build (PLUS_EXPR
, ptr_type_node
, sav
, build_int_2 (sav_ofs
, 0));
3547 u
= build (MULT_EXPR
, long_integer_type_node
,
3548 reg
, build_int_2 (sav_scale
, 0));
3549 TREE_SIDE_EFFECTS (u
) = 1;
3551 t
= build (PLUS_EXPR
, ptr_type_node
, t
, u
);
3552 TREE_SIDE_EFFECTS (t
) = 1;
3554 r
= expand_expr (t
, addr_rtx
, Pmode
, EXPAND_NORMAL
);
3556 emit_move_insn (addr_rtx
, r
);
3559 emit_jump_insn (gen_jump (lab_over
));
3561 emit_label (lab_false
);
3563 /* ... Otherwise out of the overflow area. */
3565 t
= save_expr (ovf
);
3568 /* In 64 BIT for each argument on stack, a full 64 bit slot is allocated. */
3569 if (size
< UNITS_PER_WORD
)
3571 t
= build (PLUS_EXPR
, TREE_TYPE (t
), t
, build_int_2 (UNITS_PER_WORD
-size
, 0));
3572 t
= build (MODIFY_EXPR
, TREE_TYPE (ovf
), ovf
, t
);
3573 TREE_SIDE_EFFECTS (t
) = 1;
3574 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3576 t
= save_expr (ovf
);
3579 r
= expand_expr (t
, addr_rtx
, Pmode
, EXPAND_NORMAL
);
3581 emit_move_insn (addr_rtx
, r
);
3583 t
= build (PLUS_EXPR
, TREE_TYPE (t
), t
, build_int_2 (size
, 0));
3584 t
= build (MODIFY_EXPR
, TREE_TYPE (ovf
), ovf
, t
);
3585 TREE_SIDE_EFFECTS (t
) = 1;
3586 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3588 emit_label (lab_over
);
3590 /* If less than max_regs a registers are retrieved out
3591 of register save area, increment. */
3593 u
= build (PREINCREMENT_EXPR
, TREE_TYPE (reg
), reg
,
3594 build_int_2 (n_reg
, 0));
3595 TREE_SIDE_EFFECTS (u
) = 1;
3596 expand_expr (u
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3600 r
= gen_rtx_MEM (Pmode
, addr_rtx
);
3601 set_mem_alias_set (r
, get_varargs_alias_set ());
3602 emit_move_insn (addr_rtx
, r
);
3610 /* Output assembly code for the trampoline template to
3613 On S/390, we use gpr 1 internally in the trampoline code;
3614 gpr 0 is used to hold the static chain. */
3617 s390_trampoline_template (file
)
3622 fprintf (file
, "larl\t%s,0f\n", reg_names
[1]);
3623 fprintf (file
, "lg\t%s,0(%s)\n", reg_names
[0], reg_names
[1]);
3624 fprintf (file
, "lg\t%s,8(%s)\n", reg_names
[1], reg_names
[1]);
3625 fprintf (file
, "br\t%s\n", reg_names
[1]);
3626 fprintf (file
, "0:\t.quad\t0\n");
3627 fprintf (file
, ".quad\t0\n");
3631 fprintf (file
, "basr\t%s,0\n", reg_names
[1]);
3632 fprintf (file
, "l\t%s,10(%s)\n", reg_names
[0], reg_names
[1]);
3633 fprintf (file
, "l\t%s,14(%s)\n", reg_names
[1], reg_names
[1]);
3634 fprintf (file
, "br\t%s\n", reg_names
[1]);
3635 fprintf (file
, ".long\t0\n");
3636 fprintf (file
, ".long\t0\n");
3640 /* Emit RTL insns to initialize the variable parts of a trampoline.
3641 FNADDR is an RTX for the address of the function's pure code.
3642 CXT is an RTX for the static chain value for the function. */
3645 s390_initialize_trampoline (addr
, fnaddr
, cxt
)
3650 emit_move_insn (gen_rtx
3652 memory_address (Pmode
,
3653 plus_constant (addr
, (TARGET_64BIT
? 20 : 12) ))), cxt
);
3654 emit_move_insn (gen_rtx
3656 memory_address (Pmode
,
3657 plus_constant (addr
, (TARGET_64BIT
? 28 : 16) ))), fnaddr
);
3660 /* Return rtx for 64-bit constant formed from the 32-bit subwords
3661 LOW and HIGH, independent of the host word size. */
3664 s390_gen_rtx_const_DI (high
, low
)
3668 #if HOST_BITS_PER_WIDE_INT >= 64
3670 val
= (HOST_WIDE_INT
)high
;
3672 val
|= (HOST_WIDE_INT
)low
;
3674 return GEN_INT (val
);
3676 #if HOST_BITS_PER_WIDE_INT >= 32
3677 return immed_double_const ((HOST_WIDE_INT
)low
, (HOST_WIDE_INT
)high
, DImode
);
3684 /* Output assembler code to FILE to increment profiler label # LABELNO
3685 for profiling a function entry. */
3688 s390_function_profiler (file
, labelno
)
3695 sprintf (label
, "%sP%d", LPREFIX
, labelno
);
3697 fprintf (file
, "# function profiler \n");
3699 op
[0] = gen_rtx_REG (Pmode
, RETURN_REGNUM
);
3700 op
[1] = gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
3701 op
[1] = gen_rtx_MEM (Pmode
, plus_constant (op
[1], UNITS_PER_WORD
));
3703 op
[2] = gen_rtx_REG (Pmode
, 1);
3704 op
[3] = gen_rtx_SYMBOL_REF (Pmode
, label
);
3705 SYMBOL_REF_FLAG (op
[3]) = 1;
3707 op
[4] = gen_rtx_SYMBOL_REF (Pmode
, "_mcount");
3710 op
[4] = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, op
[4]), 113);
3711 op
[4] = gen_rtx_CONST (Pmode
, op
[4]);
3716 output_asm_insn ("stg\t%0,%1", op
);
3717 output_asm_insn ("larl\t%2,%3", op
);
3718 output_asm_insn ("brasl\t%0,%4", op
);
3719 output_asm_insn ("lg\t%0,%1", op
);
3723 op
[6] = gen_label_rtx ();
3725 output_asm_insn ("st\t%0,%1", op
);
3726 output_asm_insn ("bras\t%2,%l6", op
);
3727 output_asm_insn (".long\t%3", op
);
3728 output_asm_insn (".long\t%4", op
);
3729 ASM_OUTPUT_INTERNAL_LABEL (file
, "L", CODE_LABEL_NUMBER (op
[6]));
3730 output_asm_insn ("l\t%0,0(%2)", op
);
3731 output_asm_insn ("l\t%2,4(%2)", op
);
3732 output_asm_insn ("basr\t%0,%0", op
);
3733 output_asm_insn ("l\t%0,%1", op
);
3737 op
[5] = gen_label_rtx ();
3738 op
[6] = gen_label_rtx ();
3740 output_asm_insn ("st\t%0,%1", op
);
3741 output_asm_insn ("bras\t%2,%l6", op
);
3742 ASM_OUTPUT_INTERNAL_LABEL (file
, "L", CODE_LABEL_NUMBER (op
[5]));
3743 output_asm_insn (".long\t%3-%l5", op
);
3744 output_asm_insn (".long\t%4-%l5", op
);
3745 ASM_OUTPUT_INTERNAL_LABEL (file
, "L", CODE_LABEL_NUMBER (op
[6]));
3746 output_asm_insn ("lr\t%0,%2", op
);
3747 output_asm_insn ("a\t%0,0(%2)", op
);
3748 output_asm_insn ("a\t%2,4(%2)", op
);
3749 output_asm_insn ("basr\t%0,%0", op
);
3750 output_asm_insn ("l\t%0,%1", op
);