aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/i386/scodbx.h84
-rw-r--r--gcc/config/i386/xm-dgux.h4
-rw-r--r--gcc/config/i386/xm-sun.h21
-rw-r--r--gcc/config/i386/xm-sysv3.h3
-rw-r--r--gcc/config/ia64/ia64-protos.h1
-rw-r--r--gcc/config/ia64/ia64.c34
-rw-r--r--gcc/config/ia64/ia64.h10
-rw-r--r--gcc/config/m32r/m32r.c4
-rw-r--r--gcc/config/m32r/m32r.h7
-rw-r--r--gcc/config/mips/mips.c39
-rw-r--r--gcc/config/mips/mips.md3
-rw-r--r--gcc/config/pa/pa.h3
-rw-r--r--gcc/config/rs6000/altivec.md209
-rw-r--r--gcc/config/rs6000/rs6000-protos.h1
-rw-r--r--gcc/config/rs6000/rs6000.c299
-rw-r--r--gcc/config/rs6000/sysv4.h4
-rw-r--r--gcc/config/s390/s390-protos.h3
-rw-r--r--gcc/config/s390/s390.c158
-rw-r--r--gcc/config/s390/s390.h18
-rw-r--r--gcc/config/s390/s390.md352
-rw-r--r--gcc/config/s390/tpf.h8
-rw-r--r--gcc/config/sh/sh.c4
-rw-r--r--gcc/config/sh/sh.md44
-rw-r--r--gcc/config/sh/symbian.c3
-rw-r--r--gcc/config/sparc/sparc.c64
25 files changed, 990 insertions, 390 deletions
diff --git a/gcc/config/i386/scodbx.h b/gcc/config/i386/scodbx.h
deleted file mode 100644
index 7da93053256..00000000000
--- a/gcc/config/i386/scodbx.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/* Definitions for Intel 386 running SCO Unix System V,
- using dbx-in-coff encapsulation.
- Copyright (C) 1992, 1995, 1996, 1999 Free Software Foundation, Inc.
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-#include "i386/svr3dbx.h"
-
-/* Overridden defines for SCO systems from sco.h. */
-
-/* By default, target has a 80387, uses IEEE compatible arithmetic,
- and returns float values in the 387, ie,
- (TARGET_80387 | TARGET_FLOAT_RETURNS_IN_80387)
-
- SCO's software emulation of a 387 fails to handle the `fucomp'
- opcode. fucomp is only used when generating IEEE compliant code.
- So don't make TARGET_IEEE_FP default for SCO. */
-
-#undef TARGET_SUBTARGET_DEFAULT
-#define TARGET_SUBTARGET_DEFAULT (MASK_80387 | MASK_FLOAT_RETURNS)
-
-/* Use crt1.o as a startup file and crtn.o as a closing file. */
-
-#undef STARTFILE_SPEC
-#define STARTFILE_SPEC \
- "%{!r:%{!z:svr3.ifile%s}%{z:svr3z.ifile%s}}\
- %{pg:gcrt1.o%s}%{!pg:%{p:mcrt1.o%s}%{!p:crt1.o%s}}"
-
-/* Library spec, including SCO international language support. */
-
-#undef LIB_SPEC
-#define LIB_SPEC \
- "%{p:-L/usr/lib/libp}%{pg:-L/usr/lib/libp} %{scointl:libintl.a%s} -lc"
-
-/* Specify predefined symbols in preprocessor. */
-
-#undef CPP_PREDEFINES
-#define CPP_PREDEFINES "-Dunix -DM_UNIX -DM_I386 -DM_COFF -DM_WORDSWAP -Asystem=svr3"
-
-#undef CPP_SPEC
-#define CPP_SPEC "%(cpp_cpu) %{scointl:-DM_INTERNAT}"
-
-/* This spec is used for telling cpp whether char is signed or not. */
-
-#undef SIGNED_CHAR_SPEC
-#if DEFAULT_SIGNED_CHAR
-#define SIGNED_CHAR_SPEC \
- "%{funsigned-char:-D__CHAR_UNSIGNED__ -D_CHAR_UNSIGNED}"
-#else
-#define SIGNED_CHAR_SPEC \
- "%{!fsigned-char:-D__CHAR_UNSIGNED__ -D_CHAR_UNSIGNED}"
-#endif
-
-/* caller has to pop the extra argument passed to functions that return
- structures. */
-
-#undef RETURN_POPS_ARGS
-#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) \
- ((FUNDECL) && TREE_CODE (FUNDECL) == IDENTIFIER_NODE ? 0 \
- : (TARGET_RTD \
- && (TYPE_ARG_TYPES (FUNTYPE) == 0 \
- || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (FUNTYPE))) \
- == void_type_node))) ? (SIZE) \
- : 0)
-/* On other 386 systems, the last line looks like this:
- : (aggregate_value_p (TREE_TYPE (FUNTYPE))) ? GET_MODE_SIZE (Pmode) : 0) */
-
-/* Handle #pragma pack. */
-#define HANDLE_SYSV_PRAGMA
diff --git a/gcc/config/i386/xm-dgux.h b/gcc/config/i386/xm-dgux.h
deleted file mode 100644
index 881c5c7be9d..00000000000
--- a/gcc/config/i386/xm-dgux.h
+++ /dev/null
@@ -1,4 +0,0 @@
-/* Configuration for GCC for Intel i386 running DG/ux */
-
-/* looks just like sysv4 for now */
-#include "xm-svr4.h"
diff --git a/gcc/config/i386/xm-sun.h b/gcc/config/i386/xm-sun.h
deleted file mode 100644
index 6c0f0a25630..00000000000
--- a/gcc/config/i386/xm-sun.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* Configuration for GNU C-compiler for Intel 80386 running SunOS 4.0.
- Copyright (C) 1988, 1997 Free Software Foundation, Inc.
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-#define USG
diff --git a/gcc/config/i386/xm-sysv3.h b/gcc/config/i386/xm-sysv3.h
deleted file mode 100644
index 9a655443ff5..00000000000
--- a/gcc/config/i386/xm-sysv3.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* Configuration for GCC for Intel i386 running System V Release 3. */
-
-#include "xm-svr3.h"
diff --git a/gcc/config/ia64/ia64-protos.h b/gcc/config/ia64/ia64-protos.h
index 19e1335b17e..ab5062c8c72 100644
--- a/gcc/config/ia64/ia64-protos.h
+++ b/gcc/config/ia64/ia64-protos.h
@@ -77,6 +77,7 @@ extern int ia64_function_arg_partial_nregs (CUMULATIVE_ARGS *,
enum machine_mode, tree, int);
extern void ia64_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
tree, int);
+extern int ia64_function_arg_boundary (enum machine_mode, tree);
extern void ia64_asm_output_external (FILE *, tree, const char *);
#endif /* TREE_CODE */
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index b51cc7a9408..5eed72144ef 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -3325,10 +3325,11 @@ ia64_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
cum->fp_regs = fp_regs;
}
- /* Integral and aggregates go in general registers. If we have run out of
- FR registers, then FP values must also go in general registers. This can
- happen when we have a SFmode HFA. */
- else if (! FLOAT_MODE_P (mode) || cum->fp_regs == MAX_ARGUMENT_SLOTS)
+ /* Integral and aggregates go in general registers. So do TFmode FP values.
+ If we have run out of FR registers, then other FP values must also go in
+ general registers. This can happen when we have a SFmode HFA. */
+ else if (mode == TFmode || mode == TCmode
+ || (! FLOAT_MODE_P (mode) || cum->fp_regs == MAX_ARGUMENT_SLOTS))
cum->int_regs = cum->words;
/* If there is a prototype, then FP values go in a FR register when
@@ -3351,6 +3352,31 @@ ia64_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
}
}
+/* Arguments with alignment larger than 8 bytes start at the next even
+ boundary. On ILP32 HPUX, TFmode arguments start on next even boundary
+ even though their normal alignment is 8 bytes. See ia64_function_arg. */
+
+int
+ia64_function_arg_boundary (enum machine_mode mode, tree type)
+{
+
+ if (mode == TFmode && TARGET_HPUX && TARGET_ILP32)
+ return PARM_BOUNDARY * 2;
+
+ if (type)
+ {
+ if (TYPE_ALIGN (type) > PARM_BOUNDARY)
+ return PARM_BOUNDARY * 2;
+ else
+ return PARM_BOUNDARY;
+ }
+
+ if (GET_MODE_BITSIZE (mode) > PARM_BOUNDARY)
+ return PARM_BOUNDARY * 2;
+ else
+ return PARM_BOUNDARY;
+}
+
/* Variable sized types are passed by reference. */
/* ??? At present this is a GCC extension to the IA-64 ABI. */
diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h
index 58304a9b366..aab51f83000 100644
--- a/gcc/config/ia64/ia64.h
+++ b/gcc/config/ia64/ia64.h
@@ -1376,15 +1376,11 @@ do { \
/* If defined, a C expression that gives the alignment boundary, in bits, of an
argument with the specified mode and type. */
-/* Arguments with alignment larger than 8 bytes start at the next even
- boundary. See ia64_function_arg. */
+/* Return the alignment boundary in bits for an argument with a specified
+ mode and type. */
#define FUNCTION_ARG_BOUNDARY(MODE, TYPE) \
- (((TYPE) ? (TYPE_ALIGN (TYPE) > 8 * BITS_PER_UNIT) \
- : (((((MODE) == BLKmode \
- ? int_size_in_bytes (TYPE) : GET_MODE_SIZE (MODE)) \
- + UNITS_PER_WORD - 1) / UNITS_PER_WORD) > 1)) \
- ? 128 : PARM_BOUNDARY)
+ ia64_function_arg_boundary (MODE, TYPE)
/* A C expression that is nonzero if REGNO is the number of a hard register in
which function arguments are sometimes passed. This does *not* include
diff --git a/gcc/config/m32r/m32r.c b/gcc/config/m32r/m32r.c
index 9e3404a1891..b5621568997 100644
--- a/gcc/config/m32r/m32r.c
+++ b/gcc/config/m32r/m32r.c
@@ -1591,8 +1591,8 @@ static struct m32r_frame_info zero_frame_info;
The return address and frame pointer are treated separately.
Don't consider them here. */
#define MUST_SAVE_REGISTER(regno, interrupt_p) \
-((regno) != RETURN_ADDR_REGNUM && (regno) != FRAME_POINTER_REGNUM \
- && (regs_ever_live[regno] && (!call_used_regs[regno] || interrupt_p)))
+ ((regno) != RETURN_ADDR_REGNUM && (regno) != FRAME_POINTER_REGNUM \
+ && (regs_ever_live[regno] && (!call_really_used_regs[regno] || interrupt_p)))
#define MUST_SAVE_FRAME_POINTER (regs_ever_live[FRAME_POINTER_REGNUM])
#define MUST_SAVE_RETURN_ADDR (regs_ever_live[RETURN_ADDR_REGNUM] || current_function_profile)
diff --git a/gcc/config/m32r/m32r.h b/gcc/config/m32r/m32r.h
index 9befbeee570..d5aa56b82e6 100644
--- a/gcc/config/m32r/m32r.h
+++ b/gcc/config/m32r/m32r.h
@@ -633,6 +633,8 @@ extern enum m32r_sdata m32r_sdata;
SUBTARGET_CALL_USED_REGISTERS \
}
+#define CALL_REALLY_USED_REGISTERS CALL_USED_REGISTERS
+
/* Zero or more C statements that may conditionally modify two variables
`fixed_regs' and `call_used_regs' (both of type `char []') after they
have been initialized from the two preceding macros.
@@ -649,7 +651,10 @@ extern enum m32r_sdata m32r_sdata;
do \
{ \
if (flag_pic) \
- fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
+ { \
+ fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
+ call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
+ } \
} \
while (0)
#endif
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 242c2f76aa0..048e5a8a365 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -292,6 +292,7 @@ static void mips_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,
static int symbolic_expression_p (rtx);
static void mips_select_rtx_section (enum machine_mode, rtx,
unsigned HOST_WIDE_INT);
+static void mips_function_rodata_section (tree);
static bool mips_in_small_data_p (tree);
static int mips_fpr_return_fields (tree, tree *);
static bool mips_return_in_msb (tree);
@@ -722,6 +723,8 @@ const struct mips_cpu_info mips_cpu_info_table[] = {
#define TARGET_ASM_FUNCTION_EPILOGUE mips_output_function_epilogue
#undef TARGET_ASM_SELECT_RTX_SECTION
#define TARGET_ASM_SELECT_RTX_SECTION mips_select_rtx_section
+#undef TARGET_ASM_FUNCTION_RODATA_SECTION
+#define TARGET_ASM_FUNCTION_RODATA_SECTION mips_function_rodata_section
#undef TARGET_SCHED_REORDER
#define TARGET_SCHED_REORDER mips_sched_reorder
@@ -6574,6 +6577,42 @@ mips_select_rtx_section (enum machine_mode mode, rtx x,
}
}
+/* Implement TARGET_ASM_FUNCTION_RODATA_SECTION.
+
+ The complication here is that, with the combination TARGET_ABICALLS
+ && !TARGET_GPWORD, jump tables will use absolute addresses, and should
+ therefore not be included in the read-only part of a DSO. Handle such
+ cases by selecting a normal data section instead of a read-only one.
+ The logic apes that in default_function_rodata_section. */
+
+static void
+mips_function_rodata_section (tree decl)
+{
+ if (!TARGET_ABICALLS || TARGET_GPWORD)
+ default_function_rodata_section (decl);
+ else if (decl && DECL_SECTION_NAME (decl))
+ {
+ const char *name = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
+ if (DECL_ONE_ONLY (decl) && strncmp (name, ".gnu.linkonce.t.", 16) == 0)
+ {
+ char *rname = ASTRDUP (name);
+ rname[14] = 'd';
+ named_section_real (rname, SECTION_LINKONCE | SECTION_WRITE, decl);
+ }
+ else if (flag_function_sections && flag_data_sections
+ && strncmp (name, ".text.", 6) == 0)
+ {
+ char *rname = ASTRDUP (name);
+ memcpy (rname + 1, "data", 4);
+ named_section_flags (rname, SECTION_WRITE);
+ }
+ else
+ data_section ();
+ }
+ else
+ data_section ();
+}
+
/* Implement TARGET_IN_SMALL_DATA_P. Return true if it would be safe to
access DECL using %gp_rel(...)($gp). */
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index 70428ae78ed..3bcc72a6f90 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -2828,8 +2828,7 @@ beq\t%2,%.,1b\;\
"!TARGET_MIPS16"
"<load>l\t%0,%2"
[(set_attr "type" "load")
- (set_attr "mode" "<MODE>")
- (set_attr "hazard" "none")])
+ (set_attr "mode" "<MODE>")])
(define_insn "mov_<load>r"
[(set (match_operand:GPR 0 "register_operand" "=d")
diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h
index 5c5d8bf39f0..18fb21706a3 100644
--- a/gcc/config/pa/pa.h
+++ b/gcc/config/pa/pa.h
@@ -918,7 +918,8 @@ struct hppa_args {int words, nargs_prototype, incoming, indirect; };
We use a DImode register in the parallel for 5 to 7 byte structures
so that there is only one element. This allows the object to be
correctly padded. */
-#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) (TARGET_64BIT ? upward : downward)
+#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
+ function_arg_padding ((MODE), (TYPE))
/* Do not expect to understand this without reading it several times. I'm
tempted to try and simply it, but I worry about breaking something. */
diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md
index 0eb29b1ea37..17866a9131e 100644
--- a/gcc/config/rs6000/altivec.md
+++ b/gcc/config/rs6000/altivec.md
@@ -23,6 +23,30 @@
[(UNSPEC_VSPLTISW 141)
(UNSPEC_VSPLTISH 140)
(UNSPEC_VSPLTISB 139)
+ (UNSPEC_VCMPBFP 50)
+ (UNSPEC_VCMPEQUB 51)
+ (UNSPEC_VCMPEQUH 52)
+ (UNSPEC_VCMPEQUW 53)
+ (UNSPEC_VCMPEQFP 54)
+ (UNSPEC_VCMPGEFP 55)
+ (UNSPEC_VCMPGTUB 56)
+ (UNSPEC_VCMPGTSB 57)
+ (UNSPEC_VCMPGTUH 58)
+ (UNSPEC_VCMPGTSH 59)
+ (UNSPEC_VCMPGTUW 60)
+ (UNSPEC_VCMPGTSW 61)
+ (UNSPEC_VCMPGTFP 62)
+ (UNSPEC_VSEL4SI 159)
+ (UNSPEC_VSEL4SF 160)
+ (UNSPEC_VSEL8HI 161)
+ (UNSPEC_VSEL16QI 162)
+ (UNSPEC_VCOND_V4SI 301)
+ (UNSPEC_VCOND_V4SF 302)
+ (UNSPEC_VCOND_V8HI 303)
+ (UNSPEC_VCOND_V16QI 304)
+ (UNSPEC_VCONDU_V4SI 305)
+ (UNSPEC_VCONDU_V8HI 306)
+ (UNSPEC_VCONDU_V16QI 307)
])
;; Generic LVX load instruction.
@@ -496,7 +520,8 @@
(define_insn "altivec_vcmpbfp"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v")
- (match_operand:V4SF 2 "register_operand" "v")] 50))]
+ (match_operand:V4SF 2 "register_operand" "v")]
+ UNSPEC_VCMPBFP))]
"TARGET_ALTIVEC"
"vcmpbfp %0,%1,%2"
[(set_attr "type" "veccmp")])
@@ -504,7 +529,8 @@
(define_insn "altivec_vcmpequb"
[(set (match_operand:V16QI 0 "register_operand" "=v")
(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
- (match_operand:V16QI 2 "register_operand" "v")] 51))]
+ (match_operand:V16QI 2 "register_operand" "v")]
+ UNSPEC_VCMPEQUB))]
"TARGET_ALTIVEC"
"vcmpequb %0,%1,%2"
[(set_attr "type" "vecsimple")])
@@ -512,7 +538,8 @@
(define_insn "altivec_vcmpequh"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
- (match_operand:V8HI 2 "register_operand" "v")] 52))]
+ (match_operand:V8HI 2 "register_operand" "v")]
+ UNSPEC_VCMPEQUH))]
"TARGET_ALTIVEC"
"vcmpequh %0,%1,%2"
[(set_attr "type" "vecsimple")])
@@ -520,7 +547,8 @@
(define_insn "altivec_vcmpequw"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
- (match_operand:V4SI 2 "register_operand" "v")] 53))]
+ (match_operand:V4SI 2 "register_operand" "v")]
+ UNSPEC_VCMPEQUW))]
"TARGET_ALTIVEC"
"vcmpequw %0,%1,%2"
[(set_attr "type" "vecsimple")])
@@ -528,7 +556,8 @@
(define_insn "altivec_vcmpeqfp"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v")
- (match_operand:V4SF 2 "register_operand" "v")] 54))]
+ (match_operand:V4SF 2 "register_operand" "v")]
+ UNSPEC_VCMPEQFP))]
"TARGET_ALTIVEC"
"vcmpeqfp %0,%1,%2"
[(set_attr "type" "veccmp")])
@@ -536,7 +565,8 @@
(define_insn "altivec_vcmpgefp"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v")
- (match_operand:V4SF 2 "register_operand" "v")] 55))]
+ (match_operand:V4SF 2 "register_operand" "v")]
+ UNSPEC_VCMPGEFP))]
"TARGET_ALTIVEC"
"vcmpgefp %0,%1,%2"
[(set_attr "type" "veccmp")])
@@ -544,7 +574,8 @@
(define_insn "altivec_vcmpgtub"
[(set (match_operand:V16QI 0 "register_operand" "=v")
(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
- (match_operand:V16QI 2 "register_operand" "v")] 56))]
+ (match_operand:V16QI 2 "register_operand" "v")]
+ UNSPEC_VCMPGTUB))]
"TARGET_ALTIVEC"
"vcmpgtub %0,%1,%2"
[(set_attr "type" "vecsimple")])
@@ -552,7 +583,8 @@
(define_insn "altivec_vcmpgtsb"
[(set (match_operand:V16QI 0 "register_operand" "=v")
(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
- (match_operand:V16QI 2 "register_operand" "v")] 57))]
+ (match_operand:V16QI 2 "register_operand" "v")]
+ UNSPEC_VCMPGTSB))]
"TARGET_ALTIVEC"
"vcmpgtsb %0,%1,%2"
[(set_attr "type" "vecsimple")])
@@ -560,7 +592,8 @@
(define_insn "altivec_vcmpgtuh"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
- (match_operand:V8HI 2 "register_operand" "v")] 58))]
+ (match_operand:V8HI 2 "register_operand" "v")]
+ UNSPEC_VCMPGTUH))]
"TARGET_ALTIVEC"
"vcmpgtuh %0,%1,%2"
[(set_attr "type" "vecsimple")])
@@ -568,7 +601,8 @@
(define_insn "altivec_vcmpgtsh"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
- (match_operand:V8HI 2 "register_operand" "v")] 59))]
+ (match_operand:V8HI 2 "register_operand" "v")]
+ UNSPEC_VCMPGTSH))]
"TARGET_ALTIVEC"
"vcmpgtsh %0,%1,%2"
[(set_attr "type" "vecsimple")])
@@ -576,7 +610,8 @@
(define_insn "altivec_vcmpgtuw"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
- (match_operand:V4SI 2 "register_operand" "v")] 60))]
+ (match_operand:V4SI 2 "register_operand" "v")]
+ UNSPEC_VCMPGTUW))]
"TARGET_ALTIVEC"
"vcmpgtuw %0,%1,%2"
[(set_attr "type" "vecsimple")])
@@ -584,7 +619,8 @@
(define_insn "altivec_vcmpgtsw"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
- (match_operand:V4SI 2 "register_operand" "v")] 61))]
+ (match_operand:V4SI 2 "register_operand" "v")]
+ UNSPEC_VCMPGTSW))]
"TARGET_ALTIVEC"
"vcmpgtsw %0,%1,%2"
[(set_attr "type" "vecsimple")])
@@ -592,7 +628,8 @@
(define_insn "altivec_vcmpgtfp"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v")
- (match_operand:V4SF 2 "register_operand" "v")] 62))]
+ (match_operand:V4SF 2 "register_operand" "v")]
+ UNSPEC_VCMPGTFP))]
"TARGET_ALTIVEC"
"vcmpgtfp %0,%1,%2"
[(set_attr "type" "veccmp")])
@@ -1640,11 +1677,146 @@
"vrefp %0,%1"
[(set_attr "type" "vecfloat")])
+(define_expand "vcondv4si"
+ [(set (match_operand:V4SI 0 "register_operand" "=v")
+ (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
+ (match_operand:V4SI 2 "register_operand" "v")
+ (match_operand:V4SI 3 "comparison_operator" "")
+ (match_operand:V4SI 4 "register_operand" "v")
+ (match_operand:V4SI 5 "register_operand" "v")
+ ] UNSPEC_VCOND_V4SI))]
+ "TARGET_ALTIVEC"
+ "
+{
+ if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2],
+ operands[3], operands[4], operands[5]))
+ DONE;
+ else
+ FAIL;
+}
+ ")
+
+(define_expand "vconduv4si"
+ [(set (match_operand:V4SI 0 "register_operand" "=v")
+ (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
+ (match_operand:V4SI 2 "register_operand" "v")
+ (match_operand:V4SI 3 "comparison_operator" "")
+ (match_operand:V4SI 4 "register_operand" "v")
+ (match_operand:V4SI 5 "register_operand" "v")
+ ] UNSPEC_VCONDU_V4SI))]
+ "TARGET_ALTIVEC"
+ "
+{
+ if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2],
+ operands[3], operands[4], operands[5]))
+ DONE;
+ else
+ FAIL;
+}
+ ")
+
+(define_expand "vcondv4sf"
+ [(set (match_operand:V4SF 0 "register_operand" "=v")
+ (unspec:V4SF [(match_operand:V4SI 1 "register_operand" "v")
+ (match_operand:V4SF 2 "register_operand" "v")
+ (match_operand:V4SF 3 "comparison_operator" "")
+ (match_operand:V4SF 4 "register_operand" "v")
+ (match_operand:V4SF 5 "register_operand" "v")
+ ] UNSPEC_VCOND_V4SF))]
+ "TARGET_ALTIVEC"
+ "
+{
+ if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2],
+ operands[3], operands[4], operands[5]))
+ DONE;
+ else
+ FAIL;
+}
+ ")
+
+(define_expand "vcondv8hi"
+ [(set (match_operand:V4SF 0 "register_operand" "=v")
+ (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
+ (match_operand:V8HI 2 "register_operand" "v")
+ (match_operand:V8HI 3 "comparison_operator" "")
+ (match_operand:V8HI 4 "register_operand" "v")
+ (match_operand:V8HI 5 "register_operand" "v")
+ ] UNSPEC_VCOND_V8HI))]
+ "TARGET_ALTIVEC"
+ "
+{
+ if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2],
+ operands[3], operands[4], operands[5]))
+ DONE;
+ else
+ FAIL;
+}
+ ")
+
+(define_expand "vconduv8hi"
+ [(set (match_operand:V4SF 0 "register_operand" "=v")
+ (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
+ (match_operand:V8HI 2 "register_operand" "v")
+ (match_operand:V8HI 3 "comparison_operator" "")
+ (match_operand:V8HI 4 "register_operand" "v")
+ (match_operand:V8HI 5 "register_operand" "v")
+ ] UNSPEC_VCONDU_V8HI))]
+ "TARGET_ALTIVEC"
+ "
+{
+ if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2],
+ operands[3], operands[4], operands[5]))
+ DONE;
+ else
+ FAIL;
+}
+ ")
+
+(define_expand "vcondv16qi"
+ [(set (match_operand:V4SF 0 "register_operand" "=v")
+ (unspec:V16QI [(match_operand:V4SI 1 "register_operand" "v")
+ (match_operand:V16QI 2 "register_operand" "v")
+ (match_operand:V16QI 3 "comparison_operator" "")
+ (match_operand:V16QI 4 "register_operand" "v")
+ (match_operand:V16QI 5 "register_operand" "v")
+ ] UNSPEC_VCOND_V16QI))]
+ "TARGET_ALTIVEC"
+ "
+{
+ if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2],
+ operands[3], operands[4], operands[5]))
+ DONE;
+ else
+ FAIL;
+}
+ ")
+
+(define_expand "vconduv16qi"
+ [(set (match_operand:V4SF 0 "register_operand" "=v")
+ (unspec:V16QI [(match_operand:V4SI 1 "register_operand" "v")
+ (match_operand:V16QI 2 "register_operand" "v")
+ (match_operand:V16QI 3 "comparison_operator" "")
+ (match_operand:V16QI 4 "register_operand" "v")
+ (match_operand:V16QI 5 "register_operand" "v")
+ ] UNSPEC_VCONDU_V16QI))]
+ "TARGET_ALTIVEC"
+ "
+{
+ if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2],
+ operands[3], operands[4], operands[5]))
+ DONE;
+ else
+ FAIL;
+}
+ ")
+
+
(define_insn "altivec_vsel_4si"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")
- (match_operand:V4SI 3 "register_operand" "v")] 159))]
+ (match_operand:V4SI 3 "register_operand" "v")]
+ UNSPEC_VSEL4SI))]
"TARGET_ALTIVEC"
"vsel %0,%1,%2,%3"
[(set_attr "type" "vecperm")])
@@ -1653,7 +1825,8 @@
[(set (match_operand:V4SF 0 "register_operand" "=v")
(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")
(match_operand:V4SF 2 "register_operand" "v")
- (match_operand:V4SI 3 "register_operand" "v")] 160))]
+ (match_operand:V4SI 3 "register_operand" "v")]
+ UNSPEC_VSEL4SF))]
"TARGET_ALTIVEC"
"vsel %0,%1,%2,%3"
[(set_attr "type" "vecperm")])
@@ -1662,7 +1835,8 @@
[(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
(match_operand:V8HI 2 "register_operand" "v")
- (match_operand:V8HI 3 "register_operand" "v")] 161))]
+ (match_operand:V8HI 3 "register_operand" "v")]
+ UNSPEC_VSEL8HI))]
"TARGET_ALTIVEC"
"vsel %0,%1,%2,%3"
[(set_attr "type" "vecperm")])
@@ -1671,7 +1845,8 @@
[(set (match_operand:V16QI 0 "register_operand" "=v")
(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
(match_operand:V16QI 2 "register_operand" "v")
- (match_operand:V16QI 3 "register_operand" "v")] 162))]
+ (match_operand:V16QI 3 "register_operand" "v")]
+ UNSPEC_VSEL16QI))]
"TARGET_ALTIVEC"
"vsel %0,%1,%2,%3"
[(set_attr "type" "vecperm")])
diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
index 32034dedab7..d3a3122ed5c 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -124,6 +124,7 @@ extern char * output_cbranch (rtx, const char *, int, rtx);
extern char * output_e500_flip_eq_bit (rtx, rtx);
extern rtx rs6000_emit_set_const (rtx, enum machine_mode, rtx, int);
extern int rs6000_emit_cmove (rtx, rtx, rtx, rtx);
+extern int rs6000_emit_vector_cond_expr (rtx, rtx, rtx, rtx, rtx, rtx);
extern void rs6000_emit_minmax (rtx, enum rtx_code, rtx, rtx);
extern void output_toc (FILE *, rtx, int, enum machine_mode);
extern void rs6000_initialize_trampoline (rtx, rtx, rtx);
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index be377ebf440..0d5c8b4d4b0 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -760,7 +760,15 @@ static tree rs6000_build_builtin_va_list (void);
static tree rs6000_gimplify_va_arg (tree, tree, tree *, tree *);
static bool rs6000_must_pass_in_stack (enum machine_mode, tree);
static bool rs6000_vector_mode_supported_p (enum machine_mode);
+static int get_vec_cmp_insn (enum rtx_code, enum machine_mode,
+ enum machine_mode);
+static rtx rs6000_emit_vector_compare (enum rtx_code, rtx, rtx,
+ enum machine_mode);
+static int get_vsel_insn (enum machine_mode);
+static void rs6000_emit_vector_select (rtx, rtx, rtx, rtx);
+
+const int INSN_NOT_AVAILABLE = -1;
static enum machine_mode rs6000_eh_return_filter_mode (void);
/* Hash table stuff for keeping track of TOC entries. */
@@ -11202,6 +11210,271 @@ output_e500_flip_eq_bit (rtx dst, rtx src)
return string;
}
+/* Return insn index for the vector compare instruction for given CODE,
+ and DEST_MODE, OP_MODE. Return INSN_NOT_AVAILABLE if valid insn is
+ not available. */
+
+static int
+get_vec_cmp_insn (enum rtx_code code,
+ enum machine_mode dest_mode,
+ enum machine_mode op_mode)
+{
+ if (!TARGET_ALTIVEC)
+ return INSN_NOT_AVAILABLE;
+
+ switch (code)
+ {
+ case EQ:
+ if (dest_mode == V16QImode && op_mode == V16QImode)
+ return UNSPEC_VCMPEQUB;
+ if (dest_mode == V8HImode && op_mode == V8HImode)
+ return UNSPEC_VCMPEQUH;
+ if (dest_mode == V4SImode && op_mode == V4SImode)
+ return UNSPEC_VCMPEQUW;
+ if (dest_mode == V4SImode && op_mode == V4SFmode)
+ return UNSPEC_VCMPEQFP;
+ break;
+ case GE:
+ if (dest_mode == V4SImode && op_mode == V4SFmode)
+ return UNSPEC_VCMPGEFP;
+ case GT:
+ if (dest_mode == V16QImode && op_mode == V16QImode)
+ return UNSPEC_VCMPGTSB;
+ if (dest_mode == V8HImode && op_mode == V8HImode)
+ return UNSPEC_VCMPGTSH;
+ if (dest_mode == V4SImode && op_mode == V4SImode)
+ return UNSPEC_VCMPGTSW;
+ if (dest_mode == V4SImode && op_mode == V4SFmode)
+ return UNSPEC_VCMPGTFP;
+ break;
+ case GTU:
+ if (dest_mode == V16QImode && op_mode == V16QImode)
+ return UNSPEC_VCMPGTUB;
+ if (dest_mode == V8HImode && op_mode == V8HImode)
+ return UNSPEC_VCMPGTUH;
+ if (dest_mode == V4SImode && op_mode == V4SImode)
+ return UNSPEC_VCMPGTUW;
+ break;
+ default:
+ break;
+ }
+ return INSN_NOT_AVAILABLE;
+}
+
+/* Emit vector compare for operands OP0 and OP1 using code RCODE.
+ DMODE is expected destination mode. This is a recursive function. */
+
+static rtx
+rs6000_emit_vector_compare (enum rtx_code rcode,
+ rtx op0, rtx op1,
+ enum machine_mode dmode)
+{
+ int vec_cmp_insn;
+ rtx mask;
+ enum machine_mode dest_mode;
+ enum machine_mode op_mode = GET_MODE (op1);
+
+#ifdef ENABLE_CHECKING
+ if (!TARGET_ALTIVEC)
+ abort ();
+
+ if (GET_MODE (op0) != GET_MODE (op1))
+ abort ();
+#endif
+
+ /* Floating point vector compare instructions uses destination V4SImode.
+ Move destination to appropriate mode later. */
+ if (dmode == V4SFmode)
+ dest_mode = V4SImode;
+ else
+ dest_mode = dmode;
+
+ mask = gen_reg_rtx (dest_mode);
+ vec_cmp_insn = get_vec_cmp_insn (rcode, dest_mode, op_mode);
+
+ if (vec_cmp_insn == INSN_NOT_AVAILABLE)
+ {
+ bool swap_operands = false;
+ bool try_again = false;
+ switch (rcode)
+ {
+ case LT:
+ rcode = GT;
+ swap_operands = true;
+ try_again = true;
+ break;
+ case LTU:
+ rcode = GTU;
+ swap_operands = true;
+ try_again = true;
+ break;
+ case NE:
+ /* Treat A != B as ~(A==B). */
+ {
+ enum insn_code nor_code;
+ rtx eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1,
+ dest_mode);
+
+ nor_code = one_cmpl_optab->handlers[(int)dest_mode].insn_code;
+ if (nor_code == CODE_FOR_nothing)
+ abort ();
+ emit_insn (GEN_FCN (nor_code) (mask, eq_rtx));
+
+ if (dmode != dest_mode)
+ {
+ rtx temp = gen_reg_rtx (dest_mode);
+ convert_move (temp, mask, 0);
+ return temp;
+ }
+ return mask;
+ }
+ break;
+ case GE:
+ case GEU:
+ case LE:
+ case LEU:
+ /* Try GT/GTU/LT/LTU OR EQ */
+ {
+ rtx c_rtx, eq_rtx;
+ enum insn_code ior_code;
+ enum rtx_code new_code;
+
+ if (rcode == GE)
+ new_code = GT;
+ else if (rcode == GEU)
+ new_code = GTU;
+ else if (rcode == LE)
+ new_code = LT;
+ else if (rcode == LEU)
+ new_code = LTU;
+ else
+ abort ();
+
+ c_rtx = rs6000_emit_vector_compare (new_code,
+ op0, op1, dest_mode);
+ eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1,
+ dest_mode);
+
+ ior_code = ior_optab->handlers[(int)dest_mode].insn_code;
+ if (ior_code == CODE_FOR_nothing)
+ abort ();
+ emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
+ if (dmode != dest_mode)
+ {
+ rtx temp = gen_reg_rtx (dest_mode);
+ convert_move (temp, mask, 0);
+ return temp;
+ }
+ return mask;
+ }
+ break;
+ default:
+ abort ();
+ }
+
+ if (try_again)
+ {
+ vec_cmp_insn = get_vec_cmp_insn (rcode, dest_mode, op_mode);
+ if (vec_cmp_insn == INSN_NOT_AVAILABLE)
+ /* You only get two chances. */
+ abort ();
+ }
+
+ if (swap_operands)
+ {
+ rtx tmp;
+ tmp = op0;
+ op0 = op1;
+ op1 = tmp;
+ }
+ }
+
+ emit_insn (gen_rtx_fmt_ee (SET,
+ VOIDmode,
+ mask,
+ gen_rtx_fmt_Ei (UNSPEC, dest_mode,
+ gen_rtvec (2, op0, op1),
+ vec_cmp_insn)));
+ if (dmode != dest_mode)
+ {
+ rtx temp = gen_reg_rtx (dest_mode);
+ convert_move (temp, mask, 0);
+ return temp;
+ }
+ return mask;
+}
+
+/* Return vector select instruction for MODE. Return INSN_NOT_AVAILABLE, if
+ valid insn doesn exist for given mode. */
+
+static int
+get_vsel_insn (enum machine_mode mode)
+{
+ switch (mode)
+ {
+ case V4SImode:
+ return UNSPEC_VSEL4SI;
+ break;
+ case V4SFmode:
+ return UNSPEC_VSEL4SF;
+ break;
+ case V8HImode:
+ return UNSPEC_VSEL8HI;
+ break;
+ case V16QImode:
+ return UNSPEC_VSEL16QI;
+ break;
+ default:
+ return INSN_NOT_AVAILABLE;
+ break;
+ }
+ return INSN_NOT_AVAILABLE;
+}
+
+/* Emit vector select insn where DEST is destination using
+ operands OP1, OP2 and MASK. */
+
+static void
+rs6000_emit_vector_select (rtx dest, rtx op1, rtx op2, rtx mask)
+{
+ rtx t, temp;
+ enum machine_mode dest_mode = GET_MODE (dest);
+ int vsel_insn_index = get_vsel_insn (GET_MODE (dest));
+
+ temp = gen_reg_rtx (dest_mode);
+
+ t = gen_rtx_fmt_ee (SET, VOIDmode, temp,
+ gen_rtx_fmt_Ei (UNSPEC, dest_mode,
+ gen_rtvec (3, op1, op2, mask),
+ vsel_insn_index));
+ emit_insn (t);
+ emit_move_insn (dest, temp);
+ return;
+}
+
+/* Emit vector conditional expression.
+ DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
+ CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
+
+int
+rs6000_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
+ rtx cond, rtx cc_op0, rtx cc_op1)
+{
+ enum machine_mode dest_mode = GET_MODE (dest);
+ enum rtx_code rcode = GET_CODE (cond);
+ rtx mask;
+
+ if (!TARGET_ALTIVEC)
+ return 0;
+
+ /* Get the vector mask for the given relational operations. */
+ mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
+
+ rs6000_emit_vector_select (dest, op1, op2, mask);
+
+ return 1;
+}
+
/* Emit a conditional move: move TRUE_COND to DEST if OP of the
operands of the last comparison is nonzero/true, FALSE_COND if it
is zero/false. Return 0 if the hardware has no such operation. */
@@ -11216,6 +11489,7 @@ rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
enum machine_mode compare_mode = GET_MODE (op0);
enum machine_mode result_mode = GET_MODE (dest);
rtx temp;
+ bool is_against_zero;
/* These modes should always match. */
if (GET_MODE (op1) != compare_mode
@@ -11240,6 +11514,17 @@ rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
&& GET_MODE_CLASS (compare_mode) == MODE_FLOAT)
return 0;
+ is_against_zero = op1 == CONST0_RTX (compare_mode);
+
+ /* A floating-point subtract might overflow, underflow, or produce
+ an inexact result, thus changing the floating-point flags, so it
+ can't be generated if we care about that. It's safe if one side
+ of the construct is zero, since then no subtract will be
+ generated. */
+ if (GET_MODE_CLASS (compare_mode) == MODE_FLOAT
+ && flag_trapping_math && ! is_against_zero)
+ return 0;
+
/* Eliminate half of the comparisons by switching operands, this
makes the remaining code simpler. */
if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
@@ -11272,14 +11557,18 @@ rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
|| (! rtx_equal_p (op0, true_cond)
&& ! rtx_equal_p (op1, true_cond))))
return 0;
+
/* At this point we know we can use fsel. */
/* Reduce the comparison to a comparison against zero. */
- temp = gen_reg_rtx (compare_mode);
- emit_insn (gen_rtx_SET (VOIDmode, temp,
- gen_rtx_MINUS (compare_mode, op0, op1)));
- op0 = temp;
- op1 = CONST0_RTX (compare_mode);
+ if (! is_against_zero)
+ {
+ temp = gen_reg_rtx (compare_mode);
+ emit_insn (gen_rtx_SET (VOIDmode, temp,
+ gen_rtx_MINUS (compare_mode, op0, op1)));
+ op0 = temp;
+ op1 = CONST0_RTX (compare_mode);
+ }
/* If we don't care about NaNs we can reduce some of the comparisons
down to faster ones. */
diff --git a/gcc/config/rs6000/sysv4.h b/gcc/config/rs6000/sysv4.h
index 79a44a0ef57..59bef4137ea 100644
--- a/gcc/config/rs6000/sysv4.h
+++ b/gcc/config/rs6000/sysv4.h
@@ -1110,12 +1110,12 @@ extern int fixuplabelno;
#ifdef HAVE_LD_PIE
#define STARTFILE_LINUX_SPEC "\
-%{!shared: %{pg|p:gcrt1.o%s;pie:Scrt1.o%s;:crt1.o%s}} \
+%{!shared: %{pg|p|profile:gcrt1.o%s;pie:Scrt1.o%s;:crt1.o%s}} \
%{mnewlib:ecrti.o%s;:crti.o%s} \
%{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
#else
#define STARTFILE_LINUX_SPEC "\
-%{!shared: %{pg|p:gcrt1.o%s;:crt1.o%s}} \
+%{!shared: %{pg|p|profile:gcrt1.o%s;:crt1.o%s}} \
%{mnewlib:ecrti.o%s;:crti.o%s} \
%{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
#endif
diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h
index 78b90a8b32c..4e88c1d0123 100644
--- a/gcc/config/s390/s390-protos.h
+++ b/gcc/config/s390/s390-protos.h
@@ -37,7 +37,6 @@ extern int const0_operand (rtx, enum machine_mode);
extern int consttable_operand (rtx, enum machine_mode);
extern int larl_operand (rtx, enum machine_mode);
extern int s_operand (rtx, enum machine_mode);
-extern int s_imm_operand (rtx, enum machine_mode);
extern int shift_count_operand (rtx, enum machine_mode);
extern int bras_sym_operand (rtx, enum machine_mode);
extern int load_multiple_operation (rtx, enum machine_mode);
@@ -88,6 +87,8 @@ extern rtx s390_emit_call (rtx, rtx, rtx, rtx);
extern void s390_expand_logical_operator (enum rtx_code,
enum machine_mode, rtx *);
extern bool s390_logical_operator_ok_p (rtx *);
+extern void s390_narrow_logical_operator (enum rtx_code, rtx *, rtx *);
+extern bool s390_pool_operand (rtx);
extern bool s390_output_addr_const_extra (FILE*, rtx);
extern void print_operand_address (FILE *, rtx);
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index c1414cf48f3..1d4d813458b 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -195,9 +195,9 @@ enum processor_flags s390_arch_flags;
const char *s390_tune_string; /* for -mtune=<xxx> */
const char *s390_arch_string; /* for -march=<xxx> */
-/* String to specify backchain mode. */
-const char *s390_backchain_string = ""; /* "" no-backchain ,"1" backchain,
- "2" kernel-backchain */
+/* String to specify backchain mode:
+ "" no-backchain, "1" backchain, "2" kernel-backchain. */
+const char *s390_backchain_string = TARGET_DEFAULT_BACKCHAIN;
const char *s390_warn_framesize_string;
const char *s390_warn_dynamicstack_string;
@@ -279,7 +279,6 @@ static int s390_match_ccmode_set (rtx, enum machine_mode);
static int s390_branch_condition_mask (rtx);
static const char *s390_branch_condition_mnemonic (rtx, int);
static int check_mode (rtx, enum machine_mode *);
-static int general_s_operand (rtx, enum machine_mode, int);
static int s390_short_displacement (rtx);
static int s390_decompose_address (rtx, struct s390_address *);
static rtx get_thread_pointer (void);
@@ -1167,6 +1166,27 @@ s390_logical_operator_ok_p (rtx *operands)
return true;
}
+/* Narrow logical operation CODE of memory operand MEMOP with immediate
+ operand IMMOP to switch from SS to SI type instructions. */
+
+void
+s390_narrow_logical_operator (enum rtx_code code, rtx *memop, rtx *immop)
+{
+ int def = code == AND ? -1 : 0;
+ HOST_WIDE_INT mask;
+ int part;
+
+ gcc_assert (GET_CODE (*memop) == MEM);
+ gcc_assert (!MEM_VOLATILE_P (*memop));
+
+ mask = s390_extract_part (*immop, QImode, def);
+ part = s390_single_part (*immop, GET_MODE (*memop), QImode, def);
+ gcc_assert (part >= 0);
+
+ *memop = adjust_address (*memop, QImode, part);
+ *immop = gen_int_mode (mask, QImode);
+}
+
/* Change optimizations to be performed, depending on the
optimization level.
@@ -1423,15 +1443,12 @@ larl_operand (register rtx op, enum machine_mode mode)
return 0;
}
-/* Helper routine to implement s_operand and s_imm_operand.
+/* Return true if OP is a valid S-type operand.
OP is the current operation.
- MODE is the current operation mode.
- ALLOW_IMMEDIATE specifies whether immediate operands should
- be accepted or not. */
+ MODE is the current operation mode. */
-static int
-general_s_operand (register rtx op, enum machine_mode mode,
- int allow_immediate)
+int
+s_operand (rtx op, enum machine_mode mode)
{
struct s390_address addr;
@@ -1447,58 +1464,49 @@ general_s_operand (register rtx op, enum machine_mode mode,
&& GET_CODE (SUBREG_REG (op)) == MEM)
op = SUBREG_REG (op);
- switch (GET_CODE (op))
- {
- /* Constants are OK as s-operand if ALLOW_IMMEDIATE
- is true and we are still before reload. */
- case CONST_INT:
- case CONST_DOUBLE:
- if (!allow_immediate || reload_completed)
- return 0;
- return 1;
-
- /* Memory operands are OK unless they already use an
- index register. */
- case MEM:
- if (!s390_decompose_address (XEXP (op, 0), &addr))
- return 0;
- if (addr.indx)
- return 0;
- /* Do not allow literal pool references unless ALLOW_IMMEDIATE
- is true. This prevents compares between two literal pool
- entries from being accepted. */
- if (!allow_immediate
- && addr.base && REGNO (addr.base) == BASE_REGNUM)
- return 0;
- return 1;
-
- default:
- break;
- }
+ if (GET_CODE (op) != MEM)
+ return 0;
+ if (!s390_decompose_address (XEXP (op, 0), &addr))
+ return 0;
+ if (addr.indx)
+ return 0;
- return 0;
+ return 1;
}
-/* Return true if OP is a valid S-type operand.
- OP is the current operation.
- MODE is the current operation mode. */
+/* Return true if OP is a memory operand pointing to the
+ literal pool, or an immediate operand. */
-int
-s_operand (register rtx op, enum machine_mode mode)
+bool
+s390_pool_operand (rtx op)
{
- return general_s_operand (op, mode, 0);
-}
+ struct s390_address addr;
-/* Return true if OP is a valid S-type operand or an immediate
- operand that can be addressed as S-type operand by forcing
- it into the literal pool.
- OP is the current operation.
- MODE is the current operation mode. */
+ /* Just like memory_operand, allow (subreg (mem ...))
+ after reload. */
+ if (reload_completed
+ && GET_CODE (op) == SUBREG
+ && GET_CODE (SUBREG_REG (op)) == MEM)
+ op = SUBREG_REG (op);
-int
-s_imm_operand (register rtx op, enum machine_mode mode)
-{
- return general_s_operand (op, mode, 1);
+ switch (GET_CODE (op))
+ {
+ case CONST_INT:
+ case CONST_DOUBLE:
+ return true;
+
+ case MEM:
+ if (!s390_decompose_address (XEXP (op, 0), &addr))
+ return false;
+ if (addr.base && REG_P (addr.base) && REGNO (addr.base) == BASE_REGNUM)
+ return true;
+ if (addr.indx && REG_P (addr.indx) && REGNO (addr.indx) == BASE_REGNUM)
+ return true;
+ return false;
+
+ default:
+ return false;
+ }
}
/* Return true if OP a valid shift count operand.
@@ -1577,6 +1585,21 @@ s390_extra_constraint_str (rtx op, int c, const char * str)
if (c != str[0])
abort ();
+ /* Check for offsettable variants of memory constraints. */
+ if (c == 'A')
+ {
+ /* Only accept non-volatile MEMs. */
+ if (!MEM_P (op) || MEM_VOLATILE_P (op))
+ return 0;
+
+ if ((reload_completed || reload_in_progress)
+ ? !offsettable_memref_p (op)
+ : !offsettable_nonstrict_memref_p (op))
+ return 0;
+
+ c = str[1];
+ }
+
switch (c)
{
case 'Q':
@@ -1671,7 +1694,7 @@ s390_const_ok_for_constraint_p (HOST_WIDE_INT value,
{
enum machine_mode mode, part_mode;
int def;
- unsigned char part;
+ int part, part_goal;
if (c != str[0])
abort ();
@@ -1695,7 +1718,10 @@ s390_const_ok_for_constraint_p (HOST_WIDE_INT value,
return value == 2147483647;
case 'N':
- part = str[1] - '0';
+ if (str[1] == 'x')
+ part_goal = -1;
+ else
+ part_goal = str[1] - '0';
switch (str[2])
{
@@ -1722,7 +1748,10 @@ s390_const_ok_for_constraint_p (HOST_WIDE_INT value,
if (GET_MODE_SIZE (mode) <= GET_MODE_SIZE (part_mode))
return 0;
- if (s390_single_part (GEN_INT (value), mode, part_mode, def) != part)
+ part = s390_single_part (GEN_INT (value), mode, part_mode, def);
+ if (part < 0)
+ return 0;
+ if (part_goal != -1 && part_goal != part)
return 0;
break;
@@ -6190,8 +6219,9 @@ s390_register_info (int live_regs[])
cfun_frame_layout.last_save_gpr = 6;
/* Mark f0, f2 for 31 bit and f0-f4 for 64 bit to be saved. */
- for (i = 0; i < (TARGET_64BIT ? 4 : 2); i++)
- cfun_set_fpr_bit (i);
+ if (TARGET_HARD_FLOAT)
+ for (i = 0; i < (TARGET_64BIT ? 4 : 2); i++)
+ cfun_set_fpr_bit (i);
}
if (!TARGET_64BIT)
@@ -8374,6 +8404,12 @@ s390_conditional_register_usage (void)
for (i = 18; i < 20; i++)
call_used_regs[i] = call_really_used_regs[i] = 0;
}
+
+ if (TARGET_SOFT_FLOAT)
+ {
+ for (i = 16; i < 32; i++)
+ call_used_regs[i] = fixed_regs[i] = 1;
+ }
}
/* Corresponding function to eh_return expander. */
diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h
index 4d50395b67c..11b6d84ab6d 100644
--- a/gcc/config/s390/s390.h
+++ b/gcc/config/s390/s390.h
@@ -126,11 +126,13 @@ extern int target_flags;
#define TARGET_IEEE_FLOAT 1
#ifdef DEFAULT_TARGET_64BIT
-#define TARGET_DEFAULT 0x31
+#define TARGET_DEFAULT (MASK_64BIT | MASK_ZARCH | MASK_HARD_FLOAT)
#else
-#define TARGET_DEFAULT 0x1
+#define TARGET_DEFAULT MASK_HARD_FLOAT
#endif
+#define TARGET_DEFAULT_BACKCHAIN ""
+
#define TARGET_SWITCHES \
{ { "hard-float", 1, N_("Use hardware fp")}, \
{ "soft-float", -1, N_("Don't use hardware fp")}, \
@@ -542,13 +544,14 @@ extern const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER];
#define EXTRA_CONSTRAINT_STR(OP, C, STR) \
s390_extra_constraint_str ((OP), (C), (STR))
-#define EXTRA_MEMORY_CONSTRAINT(C, STR) \
- ((C) == 'Q' || (C) == 'R' || (C) == 'S' || (C) == 'T')
-#define EXTRA_ADDRESS_CONSTRAINT(C, STR) \
+#define EXTRA_MEMORY_CONSTRAINT(C, STR) \
+ ((C) == 'Q' || (C) == 'R' || (C) == 'S' || (C) == 'T' || (C) == 'A')
+#define EXTRA_ADDRESS_CONSTRAINT(C, STR) \
((C) == 'U' || (C) == 'W' || (C) == 'Y')
-#define CONSTRAINT_LEN(C, STR) \
- ((C) == 'N' ? 5 : DEFAULT_CONSTRAINT_LEN ((C), (STR)))
+#define CONSTRAINT_LEN(C, STR) \
+ ((C) == 'N' ? 5 : \
+ (C) == 'A' ? 2 : DEFAULT_CONSTRAINT_LEN ((C), (STR)))
/* Stack layout and calling conventions. */
@@ -1015,7 +1018,6 @@ do { \
/* Define the codes that are matched by predicates in aux-output.c. */
#define PREDICATE_CODES \
{"s_operand", { SUBREG, MEM }}, \
- {"s_imm_operand", { CONST_INT, CONST_DOUBLE, SUBREG, MEM }}, \
{"shift_count_operand", { REG, SUBREG, PLUS, CONST_INT }}, \
{"bras_sym_operand",{ SYMBOL_REF, CONST }}, \
{"larl_operand", { SYMBOL_REF, CONST, CONST_INT, CONST_DOUBLE }}, \
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index 5a649932329..7d59f0c0f7e 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -34,17 +34,21 @@
;; (-524288..524287) for long displacement
;; M -- Constant integer with a value of 0x7fffffff.
;; N -- Multiple letter constraint followed by 4 parameter letters.
-;; 0..9: number of the part counting from most to least significant
-;; H,Q: mode of the part
-;; D,S,H: mode of the containing operand
-;; 0,F: value of the other parts (F - all bits set)
+;; 0..9,x: number of the part counting from most to least significant
+;; H,Q: mode of the part
+;; D,S,H: mode of the containing operand
+;; 0,F: value of the other parts (F - all bits set)
;;
;; The constraint matches if the specified part of a constant
-;; has a value different from its other parts.
+;; has a value different from its other parts. If the letter x
+;; is specified instead of a part number, the constraint matches
+;; if there is any single part with non-default value.
;; Q -- Memory reference without index register and with short displacement.
;; R -- Memory reference with index register and short displacement.
;; S -- Memory reference without index register but with long displacement.
;; T -- Memory reference with index register and long displacement.
+;; A -- Multiple letter constraint followed by Q, R, S, or T:
+;; Offsettable memory reference of type specified by second letter.
;; U -- Pointer with short displacement.
;; W -- Pointer with long displacement.
;; Y -- Shift count operand.
@@ -517,6 +521,39 @@
[(set_attr "op_type" "RS,RSY")])
+; Compare (equality) instructions
+
+(define_insn "*cmpdi_cct"
+ [(set (reg 33)
+ (compare (match_operand:DI 0 "nonimmediate_operand" "d,d,d,m,Q")
+ (match_operand:DI 1 "general_operand" "d,K,m,d,Q")))]
+ "s390_match_ccmode (insn, CCTmode) && TARGET_64BIT
+ && (!s390_pool_operand (operands[0]) || !s390_pool_operand (operands[1]))"
+ "@
+ cgr\t%0,%1
+ cghi\t%0,%c1
+ cg\t%0,%1
+ cg\t%1,%0
+ clc\t%O0(8,%R0),%1"
+ [(set_attr "op_type" "RRE,RI,RXY,RXY,SS")])
+
+(define_insn "*cmpsi_cct"
+ [(set (reg 33)
+ (compare (match_operand:SI 0 "nonimmediate_operand" "d,d,d,d,R,T,Q")
+ (match_operand:SI 1 "general_operand" "d,K,R,T,d,d,Q")))]
+ "s390_match_ccmode (insn, CCTmode)
+ && (!s390_pool_operand (operands[0]) || !s390_pool_operand (operands[1]))"
+ "@
+ cr\t%0,%1
+ chi\t%0,%c1
+ c\t%0,%1
+ cy\t%0,%1
+ c\t%1,%0
+ cy\t%1,%0
+ clc\t%O0(4,%R0),%1"
+ [(set_attr "op_type" "RR,RI,RX,RXY,RX,RXY,SS")])
+
+
; Compare (signed) instructions
(define_insn "*cmpdi_ccs_sign"
@@ -569,7 +606,7 @@
[(set (reg 33)
(compare (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,m"))
(match_operand:DI 0 "register_operand" "d,d")))]
- "s390_match_ccmode(insn, CCURmode) && TARGET_64BIT"
+ "s390_match_ccmode (insn, CCURmode) && TARGET_64BIT"
"@
clgfr\t%0,%1
clgf\t%0,%1"
@@ -577,86 +614,56 @@
(define_insn "*cmpdi_ccu"
[(set (reg 33)
- (compare (match_operand:DI 0 "register_operand" "d,d")
- (match_operand:DI 1 "general_operand" "d,m")))]
- "s390_match_ccmode(insn, CCUmode) && TARGET_64BIT"
+ (compare (match_operand:DI 0 "nonimmediate_operand" "d,d,Q")
+ (match_operand:DI 1 "general_operand" "d,m,Q")))]
+ "s390_match_ccmode (insn, CCUmode) && TARGET_64BIT
+ && (!s390_pool_operand (operands[0]) || !s390_pool_operand (operands[1]))"
"@
clgr\t%0,%1
- clg\t%0,%1"
- [(set_attr "op_type" "RRE,RXY")])
+ clg\t%0,%1
+ clc\t%O0(8,%R0),%1"
+ [(set_attr "op_type" "RRE,RXY,SS")])
(define_insn "*cmpsi_ccu"
[(set (reg 33)
- (compare (match_operand:SI 0 "register_operand" "d,d,d")
- (match_operand:SI 1 "general_operand" "d,R,T")))]
- "s390_match_ccmode(insn, CCUmode)"
+ (compare (match_operand:SI 0 "nonimmediate_operand" "d,d,d,Q")
+ (match_operand:SI 1 "general_operand" "d,R,T,Q")))]
+ "s390_match_ccmode (insn, CCUmode)
+ && (!s390_pool_operand (operands[0]) || !s390_pool_operand (operands[1]))"
"@
clr\t%0,%1
cl\t%0,%1
- cly\t%0,%1"
- [(set_attr "op_type" "RR,RX,RXY")])
+ cly\t%0,%1
+ clc\t%O0(4,%R0),%1"
+ [(set_attr "op_type" "RR,RX,RXY,SS")])
(define_insn "*cmphi_ccu"
[(set (reg 33)
- (compare (match_operand:HI 0 "register_operand" "d,d")
- (match_operand:HI 1 "s_imm_operand" "Q,S")))]
- "s390_match_ccmode(insn, CCUmode)"
+ (compare (match_operand:HI 0 "nonimmediate_operand" "d,d,Q")
+ (match_operand:HI 1 "general_operand" "Q,S,Q")))]
+ "s390_match_ccmode (insn, CCUmode)
+ && (!s390_pool_operand (operands[0]) || !s390_pool_operand (operands[1]))
+ && !register_operand (operands[1], HImode)"
"@
clm\t%0,3,%1
- clmy\t%0,3,%1"
- [(set_attr "op_type" "RS,RSY")])
+ clmy\t%0,3,%1
+ clc\t%O0(2,%R0),%1"
+ [(set_attr "op_type" "RS,RSY,SS")])
(define_insn "*cmpqi_ccu"
[(set (reg 33)
- (compare (match_operand:QI 0 "register_operand" "d,d")
- (match_operand:QI 1 "s_imm_operand" "Q,S")))]
- "s390_match_ccmode(insn, CCUmode)"
+ (compare (match_operand:QI 0 "nonimmediate_operand" "d,d,Q,S,Q")
+ (match_operand:QI 1 "general_operand" "Q,S,n,n,Q")))]
+ "s390_match_ccmode (insn, CCUmode)
+ && (!s390_pool_operand (operands[0]) || !s390_pool_operand (operands[1]))
+ && !register_operand (operands[1], QImode)"
"@
clm\t%0,1,%1
- clmy\t%0,1,%1"
- [(set_attr "op_type" "RS,RSY")])
-
-(define_insn "*cli"
- [(set (reg 33)
- (compare (match_operand:QI 0 "memory_operand" "Q,S")
- (match_operand:QI 1 "immediate_operand" "n,n")))]
- "s390_match_ccmode (insn, CCUmode)"
- "@
+ clmy\t%0,1,%1
cli\t%0,%b1
- cliy\t%0,%b1"
- [(set_attr "op_type" "SI,SIY")])
-
-(define_insn "*cmpdi_ccu_mem"
- [(set (reg 33)
- (compare (match_operand:DI 0 "s_operand" "Q")
- (match_operand:DI 1 "s_imm_operand" "Q")))]
- "s390_match_ccmode(insn, CCUmode)"
- "clc\t%O0(8,%R0),%1"
- [(set_attr "op_type" "SS")])
-
-(define_insn "*cmpsi_ccu_mem"
- [(set (reg 33)
- (compare (match_operand:SI 0 "s_operand" "Q")
- (match_operand:SI 1 "s_imm_operand" "Q")))]
- "s390_match_ccmode(insn, CCUmode)"
- "clc\t%O0(4,%R0),%1"
- [(set_attr "op_type" "SS")])
-
-(define_insn "*cmphi_ccu_mem"
- [(set (reg 33)
- (compare (match_operand:HI 0 "s_operand" "Q")
- (match_operand:HI 1 "s_imm_operand" "Q")))]
- "s390_match_ccmode(insn, CCUmode)"
- "clc\t%O0(2,%R0),%1"
- [(set_attr "op_type" "SS")])
-
-(define_insn "*cmpqi_ccu_mem"
- [(set (reg 33)
- (compare (match_operand:QI 0 "s_operand" "Q")
- (match_operand:QI 1 "s_imm_operand" "Q")))]
- "s390_match_ccmode(insn, CCUmode)"
- "clc\t%O0(1,%R0),%1"
- [(set_attr "op_type" "SS")])
+ cliy\t%0,%b1
+ clc\t%O0(1,%R0),%1"
+ [(set_attr "op_type" "RS,RSY,SI,SIY,SS")])
; DF instructions
@@ -1264,7 +1271,7 @@
(define_insn "*movstricthi"
[(set (strict_low_part (match_operand:HI 0 "register_operand" "+d,d"))
- (match_operand:HI 1 "s_imm_operand" "Q,S"))
+ (match_operand:HI 1 "memory_operand" "Q,S"))
(clobber (reg:CC 33))]
""
"@
@@ -5131,11 +5138,11 @@
[(set_attr "op_type" "RRE,RXY")])
(define_insn "*anddi3"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,d,d,Q")
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,d,d,AQ,Q")
(and:DI (match_operand:DI 1 "nonimmediate_operand"
- "%d,o,0,0,0,0,0,0,0")
+ "%d,o,0,0,0,0,0,0,0,0")
(match_operand:DI 2 "general_operand"
- "M,M,N0HDF,N1HDF,N2HDF,N3HDF,d,m,Q")))
+ "M,M,N0HDF,N1HDF,N2HDF,N3HDF,d,m,NxQDF,Q")))
(clobber (reg:CC 33))]
"TARGET_64BIT && s390_logical_operator_ok_p (operands)"
"@
@@ -5147,8 +5154,19 @@
nill\t%0,%j2
ngr\t%0,%2
ng\t%0,%2
+ #
nc\t%O0(8,%R0),%2"
- [(set_attr "op_type" "RRE,RXE,RI,RI,RI,RI,RRE,RXY,SS")])
+ [(set_attr "op_type" "RRE,RXE,RI,RI,RI,RI,RRE,RXY,SI,SS")])
+
+(define_split
+ [(set (match_operand:DI 0 "s_operand" "")
+ (and:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
+ (clobber (reg:CC 33))]
+ "reload_completed"
+ [(parallel
+ [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
+ (clobber (reg:CC 33))])]
+ "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
(define_expand "anddi3"
[(set (match_operand:DI 0 "nonimmediate_operand" "")
@@ -5192,9 +5210,11 @@
[(set_attr "op_type" "RR,RX,RXY")])
(define_insn "*andsi3_zarch"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,d,Q")
- (and:SI (match_operand:SI 1 "nonimmediate_operand" "%d,o,0,0,0,0,0,0")
- (match_operand:SI 2 "general_operand" "M,M,N0HSF,N1HSF,d,R,T,Q")))
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,d,AQ,Q")
+ (and:SI (match_operand:SI 1 "nonimmediate_operand"
+ "%d,o,0,0,0,0,0,0,0")
+ (match_operand:SI 2 "general_operand"
+ "M,M,N0HSF,N1HSF,d,R,T,NxQSF,Q")))
(clobber (reg:CC 33))]
"TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
"@
@@ -5205,20 +5225,32 @@
nr\t%0,%2
n\t%0,%2
ny\t%0,%2
+ #
nc\t%O0(4,%R0),%2"
- [(set_attr "op_type" "RRE,RXE,RI,RI,RR,RX,RXY,SS")])
+ [(set_attr "op_type" "RRE,RXE,RI,RI,RR,RX,RXY,SI,SS")])
(define_insn "*andsi3_esa"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,Q")
- (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0")
- (match_operand:SI 2 "general_operand" "d,R,Q")))
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,AQ,Q")
+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
+ (match_operand:SI 2 "general_operand" "d,R,NxQSF,Q")))
(clobber (reg:CC 33))]
"!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
"@
nr\t%0,%2
n\t%0,%2
+ #
nc\t%O0(4,%R0),%2"
- [(set_attr "op_type" "RR,RX,SS")])
+ [(set_attr "op_type" "RR,RX,SI,SS")])
+
+(define_split
+ [(set (match_operand:SI 0 "s_operand" "")
+ (and:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
+ (clobber (reg:CC 33))]
+ "reload_completed"
+ [(parallel
+ [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
+ (clobber (reg:CC 33))])]
+ "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
(define_expand "andsi3"
[(set (match_operand:SI 0 "nonimmediate_operand" "")
@@ -5233,27 +5265,39 @@
;
(define_insn "*andhi3_zarch"
- [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,Q")
- (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
- (match_operand:HI 2 "general_operand" "d,n,Q")))
+ [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,AQ,Q")
+ (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0,0")
+ (match_operand:HI 2 "general_operand" "d,n,NxQHF,Q")))
(clobber (reg:CC 33))]
"TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
"@
nr\t%0,%2
nill\t%0,%x2
+ #
nc\t%O0(2,%R0),%2"
- [(set_attr "op_type" "RR,RI,SS")])
+ [(set_attr "op_type" "RR,RI,SI,SS")])
(define_insn "*andhi3_esa"
- [(set (match_operand:HI 0 "nonimmediate_operand" "=d,Q")
- (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
- (match_operand:HI 2 "general_operand" "d,Q")))
+ [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q")
+ (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
+ (match_operand:HI 2 "general_operand" "d,NxQHF,Q")))
(clobber (reg:CC 33))]
"!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
"@
nr\t%0,%2
+ #
nc\t%O0(2,%R0),%2"
- [(set_attr "op_type" "RR,SS")])
+ [(set_attr "op_type" "RR,SI,SS")])
+
+(define_split
+ [(set (match_operand:HI 0 "s_operand" "")
+ (and:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
+ (clobber (reg:CC 33))]
+ "reload_completed"
+ [(parallel
+ [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
+ (clobber (reg:CC 33))])]
+ "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
(define_expand "andhi3"
[(set (match_operand:HI 0 "nonimmediate_operand" "")
@@ -5336,10 +5380,10 @@
[(set_attr "op_type" "RRE,RXY")])
(define_insn "*iordi3"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,Q")
- (ior:DI (match_operand:DI 1 "nonimmediate_operand" "0,0,0,0,0,0,0")
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,AQ,Q")
+ (ior:DI (match_operand:DI 1 "nonimmediate_operand" "0,0,0,0,0,0,0,0")
(match_operand:DI 2 "general_operand"
- "N0HD0,N1HD0,N2HD0,N3HD0,d,m,Q")))
+ "N0HD0,N1HD0,N2HD0,N3HD0,d,m,NxQD0,Q")))
(clobber (reg:CC 33))]
"TARGET_64BIT && s390_logical_operator_ok_p (operands)"
"@
@@ -5349,8 +5393,19 @@
oill\t%0,%i2
ogr\t%0,%2
og\t%0,%2
+ #
oc\t%O0(8,%R0),%2"
- [(set_attr "op_type" "RI,RI,RI,RI,RRE,RXY,SS")])
+ [(set_attr "op_type" "RI,RI,RI,RI,RRE,RXY,SI,SS")])
+
+(define_split
+ [(set (match_operand:DI 0 "s_operand" "")
+ (ior:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
+ (clobber (reg:CC 33))]
+ "reload_completed"
+ [(parallel
+ [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
+ (clobber (reg:CC 33))])]
+ "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
(define_expand "iordi3"
[(set (match_operand:DI 0 "nonimmediate_operand" "")
@@ -5392,9 +5447,9 @@
[(set_attr "op_type" "RR,RX,RXY")])
(define_insn "*iorsi3_zarch"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,Q")
- (ior:SI (match_operand:SI 1 "nonimmediate_operand" "0,0,0,0,0,0")
- (match_operand:SI 2 "general_operand" "N0HS0,N1HS0,d,R,T,Q")))
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,AQ,Q")
+ (ior:SI (match_operand:SI 1 "nonimmediate_operand" "0,0,0,0,0,0,0")
+ (match_operand:SI 2 "general_operand" "N0HS0,N1HS0,d,R,T,NxQS0,Q")))
(clobber (reg:CC 33))]
"TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
"@
@@ -5403,20 +5458,32 @@
or\t%0,%2
o\t%0,%2
oy\t%0,%2
+ #
oc\t%O0(4,%R0),%2"
- [(set_attr "op_type" "RI,RI,RR,RX,RXY,SS")])
+ [(set_attr "op_type" "RI,RI,RR,RX,RXY,SI,SS")])
(define_insn "*iorsi3_esa"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,Q")
- (ior:SI (match_operand:SI 1 "nonimmediate_operand" "0,0,0")
- (match_operand:SI 2 "general_operand" "d,R,Q")))
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,AQ,Q")
+ (ior:SI (match_operand:SI 1 "nonimmediate_operand" "0,0,0,0")
+ (match_operand:SI 2 "general_operand" "d,R,NxQS0,Q")))
(clobber (reg:CC 33))]
"!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
"@
or\t%0,%2
o\t%0,%2
+ #
oc\t%O0(4,%R0),%2"
- [(set_attr "op_type" "RR,RX,SS")])
+ [(set_attr "op_type" "RR,RX,SI,SS")])
+
+(define_split
+ [(set (match_operand:SI 0 "s_operand" "")
+ (ior:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
+ (clobber (reg:CC 33))]
+ "reload_completed"
+ [(parallel
+ [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
+ (clobber (reg:CC 33))])]
+ "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
(define_expand "iorsi3"
[(set (match_operand:SI 0 "nonimmediate_operand" "")
@@ -5431,27 +5498,39 @@
;
(define_insn "*iorhi3_zarch"
- [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,Q")
- (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
- (match_operand:HI 2 "general_operand" "d,n,Q")))
+ [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,AQ,Q")
+ (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0,0")
+ (match_operand:HI 2 "general_operand" "d,n,NxQH0,Q")))
(clobber (reg:CC 33))]
"TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
"@
or\t%0,%2
oill\t%0,%x2
+ #
oc\t%O0(2,%R0),%2"
- [(set_attr "op_type" "RR,RI,SS")])
+ [(set_attr "op_type" "RR,RI,SI,SS")])
(define_insn "*iorhi3_esa"
- [(set (match_operand:HI 0 "nonimmediate_operand" "=d,Q")
- (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
- (match_operand:HI 2 "general_operand" "d,Q")))
+ [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q")
+ (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
+ (match_operand:HI 2 "general_operand" "d,NxQH0,Q")))
(clobber (reg:CC 33))]
"!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
"@
or\t%0,%2
+ #
oc\t%O0(2,%R0),%2"
- [(set_attr "op_type" "RR,SS")])
+ [(set_attr "op_type" "RR,SI,SS")])
+
+(define_split
+ [(set (match_operand:HI 0 "s_operand" "")
+ (ior:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
+ (clobber (reg:CC 33))]
+ "reload_completed"
+ [(parallel
+ [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
+ (clobber (reg:CC 33))])]
+ "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
(define_expand "iorhi3"
[(set (match_operand:HI 0 "nonimmediate_operand" "")
@@ -5534,16 +5613,27 @@
[(set_attr "op_type" "RRE,RXY")])
(define_insn "*xordi3"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,Q")
- (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
- (match_operand:DI 2 "general_operand" "d,m,Q")))
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,AQ,Q")
+ (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,0")
+ (match_operand:DI 2 "general_operand" "d,m,NxQD0,Q")))
(clobber (reg:CC 33))]
"TARGET_64BIT && s390_logical_operator_ok_p (operands)"
"@
xgr\t%0,%2
xg\t%0,%2
+ #
xc\t%O0(8,%R0),%2"
- [(set_attr "op_type" "RRE,RXY,SS")])
+ [(set_attr "op_type" "RRE,RXY,SI,SS")])
+
+(define_split
+ [(set (match_operand:DI 0 "s_operand" "")
+ (xor:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
+ (clobber (reg:CC 33))]
+ "reload_completed"
+ [(parallel
+ [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
+ (clobber (reg:CC 33))])]
+ "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
(define_expand "xordi3"
[(set (match_operand:DI 0 "nonimmediate_operand" "")
@@ -5585,17 +5675,28 @@
[(set_attr "op_type" "RR,RX,RXY")])
(define_insn "*xorsi3"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,Q")
- (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
- (match_operand:SI 2 "general_operand" "d,R,T,Q")))
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,AQ,Q")
+ (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0,0")
+ (match_operand:SI 2 "general_operand" "d,R,T,NxQS0,Q")))
(clobber (reg:CC 33))]
"s390_logical_operator_ok_p (operands)"
"@
xr\t%0,%2
x\t%0,%2
xy\t%0,%2
+ #
xc\t%O0(4,%R0),%2"
- [(set_attr "op_type" "RR,RX,RXY,SS")])
+ [(set_attr "op_type" "RR,RX,RXY,SI,SS")])
+
+(define_split
+ [(set (match_operand:SI 0 "s_operand" "")
+ (xor:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
+ (clobber (reg:CC 33))]
+ "reload_completed"
+ [(parallel
+ [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
+ (clobber (reg:CC 33))])]
+ "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
(define_expand "xorsi3"
[(set (match_operand:SI 0 "nonimmediate_operand" "")
@@ -5610,15 +5711,26 @@
;
(define_insn "*xorhi3"
- [(set (match_operand:HI 0 "nonimmediate_operand" "=d,Q")
- (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
- (match_operand:HI 2 "general_operand" "d,Q")))
+ [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q")
+ (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
+ (match_operand:HI 2 "general_operand" "d,NxQH0,Q")))
(clobber (reg:CC 33))]
"s390_logical_operator_ok_p (operands)"
"@
xr\t%0,%2
+ #
xc\t%O0(2,%R0),%2"
- [(set_attr "op_type" "RR,SS")])
+ [(set_attr "op_type" "RR,SI,SS")])
+
+(define_split
+ [(set (match_operand:HI 0 "s_operand" "")
+ (xor:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
+ (clobber (reg:CC 33))]
+ "reload_completed"
+ [(parallel
+ [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
+ (clobber (reg:CC 33))])]
+ "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
(define_expand "xorhi3"
[(set (match_operand:HI 0 "nonimmediate_operand" "")
diff --git a/gcc/config/s390/tpf.h b/gcc/config/s390/tpf.h
index 8ba13e25412..e6a016a7771 100644
--- a/gcc/config/s390/tpf.h
+++ b/gcc/config/s390/tpf.h
@@ -54,9 +54,13 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#undef STACK_POINTER_OFFSET
#define STACK_POINTER_OFFSET 448
-/* When building for TPF, set a generic default target that is 64 bits. */
+/* When building for TPF, set a generic default target that is 64 bits.
+ Also, enable TPF profiling support and the standard backchain by default. */
#undef TARGET_DEFAULT
-#define TARGET_DEFAULT 0xb3
+#define TARGET_DEFAULT (MASK_64BIT | MASK_ZARCH | MASK_HARD_FLOAT \
+ | MASK_TPF_PROFILING)
+#undef TARGET_DEFAULT_BACKCHAIN
+#define TARGET_DEFAULT_BACKCHAIN "1"
/* Exception handling. */
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 349d981ccc9..d88e159bd1f 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -9413,7 +9413,7 @@ int
sh_dwarf_calling_convention (tree func)
{
if (sh_attr_renesas_p (func))
- return DW_CC_renesas_sh;
+ return DW_CC_GNU_renesas_sh;
return DW_CC_normal;
}
@@ -10095,7 +10095,7 @@ sh_init_cumulative_args (CUMULATIVE_ARGS * pcum,
pcum->prototype_p = FALSE;
if (mode != VOIDmode)
{
- pcum->call_cookie =
+ pcum->call_cookie =
CALL_COOKIE_RET_TRAMP (TARGET_SHCOMPACT
&& GET_MODE_SIZE (mode) > 4
&& BASE_RETURN_VALUE_REG (mode) == FIRST_RET_REG);
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index 5adcac22664..dd9f216b587 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -6869,8 +6869,8 @@
(define_insn "tls_global_dynamic"
[(set (match_operand:SI 0 "register_operand" "=&z")
- (call (unspec:SI [(match_operand:SI 1 "" "")]
- UNSPEC_TLSGD)
+ (call (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
+ UNSPEC_TLSGD))
(const_int 0)))
(use (reg:PSI FPSCR_REG))
(use (reg:SI PIC_REG))
@@ -6898,8 +6898,8 @@ mov.l\\t1f,r4\\n\\
(define_insn "tls_local_dynamic"
[(set (match_operand:SI 0 "register_operand" "=&z")
- (call (unspec:SI [(match_operand:SI 1 "" "")]
- UNSPEC_TLSLDM)
+ (call (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
+ UNSPEC_TLSLDM))
(const_int 0)))
(use (reg:PSI FPSCR_REG))
(use (reg:SI PIC_REG))
@@ -10951,17 +10951,45 @@ mov.l\\t1f,r0\\n\\
"byterev %1, %0"
[(set_attr "type" "arith_media")])
-(define_insn "prefetch"
+(define_insn "prefetch_media"
[(prefetch (match_operand:QI 0 "address_operand" "p")
(match_operand:SI 1 "const_int_operand" "n")
(match_operand:SI 2 "const_int_operand" "n"))]
- "TARGET_SHMEDIA || TARGET_HARD_SH4"
+ "TARGET_SHMEDIA"
"*
{
- if (TARGET_HARD_SH4)
- return \"pref @%0\";
operands[0] = gen_rtx_MEM (QImode, operands[0]);
output_asm_insn (\"ld%M0.b %m0,r63\", operands);
return \"\";
}"
[(set_attr "type" "other")])
+
+(define_insn "prefetch_i4"
+ [(prefetch (match_operand:SI 0 "register_operand" "r")
+ (match_operand:SI 1 "const_int_operand" "n")
+ (match_operand:SI 2 "const_int_operand" "n"))]
+ "TARGET_HARD_SH4"
+ "*
+{
+ return \"pref @%0\";
+}"
+ [(set_attr "type" "other")])
+
+(define_expand "prefetch"
+ [(prefetch (match_operand:QI 0 "address_operand" "p")
+ (match_operand:SI 1 "const_int_operand" "n")
+ (match_operand:SI 2 "const_int_operand" "n"))]
+ "TARGET_SHMEDIA || TARGET_HARD_SH4"
+ "
+{
+ if (TARGET_HARD_SH4 && ! register_operand (operands[0], SImode))
+ {
+ rtx reg = gen_reg_rtx (SImode);
+ emit_move_insn (reg, operands[0]);
+ operands[0] = reg;
+ }
+
+ emit_insn ((TARGET_SHMEDIA ? gen_prefetch_media : gen_prefetch_i4)
+ (operands[0], operands[1], operands[2]));
+ DONE;
+}")
diff --git a/gcc/config/sh/symbian.c b/gcc/config/sh/symbian.c
index e4b0d2bc225..02b95f5970d 100644
--- a/gcc/config/sh/symbian.c
+++ b/gcc/config/sh/symbian.c
@@ -559,8 +559,7 @@ symbian_possibly_export_base_class (tree base_class)
tree methods;
int len;
- if (! (TYPE_POLYMORPHIC_P (base_class)
- || TYPE_USES_VIRTUAL_BASECLASSES (base_class)))
+ if (! (TYPE_CONTAINS_VPTR_P (base_class)))
return;
methods = CLASSTYPE_METHOD_VEC (base_class);
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index aa1fa0905b1..3f75954e6cc 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -1547,23 +1547,7 @@ input_operand (rtx op, enum machine_mode mode)
/* Check for valid MEM forms. */
if (GET_CODE (op) == MEM)
- {
- rtx inside = XEXP (op, 0);
-
- if (GET_CODE (inside) == LO_SUM)
- {
- /* We can't allow these because all of the splits
- (eventually as they trickle down into DFmode
- splits) require offsettable memory references. */
- if (! TARGET_V9
- && GET_MODE (op) == TFmode)
- return 0;
-
- return (register_operand (XEXP (inside, 0), Pmode)
- && CONSTANT_P (XEXP (inside, 1)));
- }
- return memory_address_p (mode, inside);
- }
+ return memory_address_p (mode, XEXP (op, 0));
return 0;
}
@@ -3516,15 +3500,14 @@ legitimate_address_p (enum machine_mode mode, rtx addr, int strict)
else if ((REG_P (rs1) || GET_CODE (rs1) == SUBREG)
&& (REG_P (rs2) || GET_CODE (rs2) == SUBREG))
{
- /* We prohibit REG + REG for TFmode when there are no instructions
- which accept REG+REG instructions. We do this because REG+REG
- is not an offsetable address. If we get the situation in reload
+ /* We prohibit REG + REG for TFmode when there are no quad move insns
+ and we consequently need to split. We do this because REG+REG
+ is not an offsettable address. If we get the situation in reload
where source and destination of a movtf pattern are both MEMs with
REG+REG address, then only one of them gets converted to an
- offsetable address. */
+ offsettable address. */
if (mode == TFmode
- && !(TARGET_FPU && TARGET_ARCH64 && TARGET_V9
- && TARGET_HARD_QUAD))
+ && ! (TARGET_FPU && TARGET_ARCH64 && TARGET_HARD_QUAD))
return 0;
/* We prohibit REG + REG on ARCH32 if not optimizing for
@@ -3557,10 +3540,25 @@ legitimate_address_p (enum machine_mode mode, rtx addr, int strict)
if (! CONSTANT_P (imm1) || tls_symbolic_operand (rs1))
return 0;
- /* We can't allow TFmode, because an offset greater than or equal to the
- alignment (8) may cause the LO_SUM to overflow if !v9. */
- if (mode == TFmode && !TARGET_V9)
- return 0;
+ if (USE_AS_OFFSETABLE_LO10)
+ {
+ /* We can't allow TFmode, because an offset greater than or equal to
+ the alignment (8) may cause the LO_SUM to overflow if !v9. */
+ if (mode == TFmode && ! TARGET_V9)
+ return 0;
+ }
+ else
+ {
+ /* We prohibit LO_SUM for TFmode when there are no quad move insns
+ and we consequently need to split. We do this because LO_SUM
+ is not an offsettable address. If we get the situation in reload
+ where source and destination of a movtf pattern are both MEMs with
+ LO_SUM address, then only one of them gets converted to an
+ offsettable address. */
+ if (mode == TFmode
+ && ! (TARGET_FPU && TARGET_ARCH64 && TARGET_HARD_QUAD))
+ return 0;
+ }
}
else if (GET_CODE (addr) == CONST_INT && SMALL_INT (addr))
return 1;
@@ -6024,7 +6022,7 @@ sparc_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
bool indirect;
tree ptrtype = build_pointer_type (type);
- if (pass_by_reference (NULL, TYPE_MODE (type), type, 0))
+ if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
{
indirect = true;
size = rsize = UNITS_PER_WORD;
@@ -6044,7 +6042,7 @@ sparc_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
align = 2 * UNITS_PER_WORD;
/* SPARC-V9 ABI states that structures up to 16 bytes in size
- are given whole slots as needed. */
+ are left-justified in their slots. */
if (AGGREGATE_TYPE_P (type))
{
if (size == 0)
@@ -6074,7 +6072,7 @@ sparc_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
if (indirect)
{
addr = fold_convert (build_pointer_type (ptrtype), addr);
- addr = build_fold_indirect_ref (addr);
+ addr = build_va_arg_indirect_ref (addr);
}
/* If the address isn't aligned properly for the type,
we may need to copy to a temporary.
@@ -6103,7 +6101,7 @@ sparc_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
incr = build2 (MODIFY_EXPR, ptr_type_node, valist, incr);
gimplify_and_add (incr, post_p);
- return build_fold_indirect_ref (addr);
+ return build_va_arg_indirect_ref (addr);
}
/* Return the string to output an unconditional branch to LABEL, which is
@@ -8543,7 +8541,7 @@ sparc_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
{
/* We will emit a regular sibcall below, so we need to instruct
output_sibcall that we are in a leaf function. */
- sparc_leaf_function_p = 1;
+ sparc_leaf_function_p = current_function_uses_only_leaf_regs = 1;
/* This will cause final.c to invoke leaf_renumber_regs so we
must behave as if we were in a not-yet-leafified function. */
@@ -8553,7 +8551,7 @@ sparc_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
{
/* We will emit the sibcall manually below, so we will need to
manually spill non-leaf registers. */
- sparc_leaf_function_p = 0;
+ sparc_leaf_function_p = current_function_uses_only_leaf_regs = 0;
/* We really are in a leaf function. */
int_arg_first = SPARC_OUTGOING_INT_ARG_FIRST;