aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2002-03-24 00:03:44 -0800
committerRichard Henderson <rth@gcc.gnu.org>2002-03-24 00:03:44 -0800
commitc6e6f5c196bf7bdf6b0cff89b7de8ba863e2f63f (patch)
treefb1b0974f40ce418449b1ea3d0ecf1276a70611d
parentd88e57d1fb9910215fb1fc57d6da2ae6799a8529 (diff)
downloadgcc-c6e6f5c196bf7bdf6b0cff89b7de8ba863e2f63f.zip
gcc-c6e6f5c196bf7bdf6b0cff89b7de8ba863e2f63f.tar.gz
gcc-c6e6f5c196bf7bdf6b0cff89b7de8ba863e2f63f.tar.bz2
re PR rtl-optimization/5742 (bug with -freg-struct-return and functions returning 1 byte values)
PR optimization/5742 * machmode.def: Add inner mode field to complex modes. * config/mips/mips.c (mips_function_value): Always define. Add new argument to handle libcalls. * config/mips/mips.h (LIBCALL_VALUE): Use mips_function_value. (FUNCTION_VALUE): Likewise. * config/mips/abi64.h (FUNCTION_VALUE): Remove. * config/mips/mips-protos.h: Update. From-SVN: r51250
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/config/mips/abi64.h3
-rw-r--r--gcc/config/mips/mips-protos.h3
-rw-r--r--gcc/config/mips/mips.c28
-rw-r--r--gcc/config/mips/mips.h17
-rw-r--r--gcc/machmode.def30
6 files changed, 47 insertions, 45 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5320d13..f75a463 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+2002-03-24 Richard Henderson <rth@redhat.com>
+
+ PR optimization/5742
+ * machmode.def: Add inner mode field to complex modes.
+ * config/mips/mips.c (mips_function_value): Always define. Add
+ new argument to handle libcalls.
+ * config/mips/mips.h (LIBCALL_VALUE): Use mips_function_value.
+ (FUNCTION_VALUE): Likewise.
+ * config/mips/abi64.h (FUNCTION_VALUE): Remove.
+ * config/mips/mips-protos.h: Update.
+
2002-03-23 Richard Henderson <rth@redhat.com>
* config/sparc/sparc.c (sparc_emit_floatunsdi): New.
diff --git a/gcc/config/mips/abi64.h b/gcc/config/mips/abi64.h
index 5ba856f..a76f8c0 100644
--- a/gcc/config/mips/abi64.h
+++ b/gcc/config/mips/abi64.h
@@ -99,9 +99,6 @@ Boston, MA 02111-1307, USA. */
&& (FUNCTION_ARG_PADDING (MODE, TYPE) \
== (BYTES_BIG_ENDIAN ? upward : downward)))))
-#undef FUNCTION_VALUE
-#define FUNCTION_VALUE(VALTYPE, FUNC) mips_function_value (VALTYPE, FUNC)
-
#define STRICT_ARGUMENT_NAMING (mips_abi != ABI_32 && mips_abi != ABI_O64)
/* A C expression that indicates when an argument must be passed by
diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h
index 8332782..1ea662e 100644
--- a/gcc/config/mips/mips-protos.h
+++ b/gcc/config/mips/mips-protos.h
@@ -50,7 +50,8 @@ extern struct rtx_def * mips16_gp_pseudo_reg PARAMS ((void));
#ifdef ASM_OUTPUT_UNDEF_FUNCTION
extern int mips_output_external_libcall PARAMS ((FILE *, const char *));
#endif /* ASM_OUTPUT_UNDEF_FUNCTION */
-extern struct rtx_def *mips_function_value PARAMS ((tree, tree));
+extern struct rtx_def *mips_function_value PARAMS ((tree, tree,
+ enum machine_mode));
extern unsigned int mips_hard_regno_nregs PARAMS ((int,
enum machine_mode));
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index f5bf777..51cd562 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -7912,22 +7912,25 @@ mips_select_section (decl, reloc)
}
}
-#ifdef MIPS_ABI_DEFAULT
-
-/* Support functions for the 64 bit ABI. */
-
-/* Return register to use for a function return value with VALTYPE for function
- FUNC. */
+/* Return register to use for a function return value with VALTYPE for
+ function FUNC. MODE is used instead of VALTYPE for LIBCALLs. */
rtx
-mips_function_value (valtype, func)
+mips_function_value (valtype, func, mode)
tree valtype;
tree func ATTRIBUTE_UNUSED;
+ enum machine_mode mode;
{
int reg = GP_RETURN;
- enum machine_mode mode = TYPE_MODE (valtype);
- enum mode_class mclass = GET_MODE_CLASS (mode);
- int unsignedp = TREE_UNSIGNED (valtype);
+ enum mode_class mclass;
+ int unsignedp = 1;
+
+ if (valtype)
+ {
+ mode = TYPE_MODE (valtype);
+ unsignedp = TREE_UNSIGNED (valtype);
+ }
+ mclass = GET_MODE_CLASS (mode);
/* Since we define PROMOTE_FUNCTION_RETURN, we must promote the mode
just as PROMOTE_MODE does. */
@@ -7939,7 +7942,7 @@ mips_function_value (valtype, func)
else if (mclass == MODE_COMPLEX_FLOAT
&& GET_MODE_SIZE (mode) <= UNITS_PER_FPVALUE * 2)
{
- enum machine_mode cmode = TYPE_MODE (TREE_TYPE (valtype));
+ enum machine_mode cmode = GET_MODE_INNER (mode);
return gen_rtx_PARALLEL
(VOIDmode,
@@ -7952,7 +7955,7 @@ mips_function_value (valtype, func)
GEN_INT (GET_MODE_SIZE (cmode)))));
}
- else if (TREE_CODE (valtype) == RECORD_TYPE
+ else if (valtype && TREE_CODE (valtype) == RECORD_TYPE
&& mips_abi != ABI_32
&& mips_abi != ABI_O64
&& mips_abi != ABI_EABI)
@@ -8019,7 +8022,6 @@ mips_function_value (valtype, func)
return gen_rtx_REG (mode, reg);
}
-#endif
/* The implementation of FUNCTION_ARG_PASS_BY_REFERENCE. Return
nonzero when an argument must be passed by reference. */
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index 62bb9483d..16b34ab 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -2696,25 +2696,16 @@ extern struct mips_frame_info current_frame_info;
PROMOTE_FUNCTION_RETURN, we must promote the mode just as
PROMOTE_MODE does. */
-#define LIBCALL_VALUE(MODE) \
- gen_rtx (REG, \
- ((GET_MODE_CLASS (MODE) != MODE_INT \
- || GET_MODE_SIZE (MODE) >= 4) \
- ? (MODE) \
- : SImode), \
- ((GET_MODE_CLASS (MODE) == MODE_FLOAT \
- && (! TARGET_SINGLE_FLOAT \
- || GET_MODE_SIZE (MODE) <= 4)) \
- ? FP_RETURN \
- : GP_RETURN))
+#define LIBCALL_VALUE(MODE) \
+ mips_function_value (NULL_TREE, NULL, (MODE))
/* Define how to find the value returned by a function.
VALTYPE is the data type of the value (as a tree).
If the precise function being called is known, FUNC is its FUNCTION_DECL;
otherwise, FUNC is 0. */
-#define FUNCTION_VALUE(VALTYPE, FUNC) LIBCALL_VALUE (TYPE_MODE (VALTYPE))
-
+#define FUNCTION_VALUE(VALTYPE, FUNC) \
+ mips_function_value ((VALTYPE), (FUNC), VOIDmode)
/* 1 if N is a possible register number for a function value.
On the MIPS, R2 R3 and F0 F2 are the only register thus used.
diff --git a/gcc/machmode.def b/gcc/machmode.def
index eedff97..6212334 100644
--- a/gcc/machmode.def
+++ b/gcc/machmode.def
@@ -65,8 +65,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
The ordering is by increasing byte size, with QI coming before HI,
HI before SI, etc.
- Eigth arg is the mode of the internal elements in a vector.
- VOIDmode if not a vector.
+ Eigth arg is the mode of the internal elements in a vector or
+ complex, and VOIDmode if not applicable.
*/
/* VOIDmode is used when no mode needs to be specified,
@@ -98,19 +98,19 @@ DEF_MACHMODE (XFmode, "XF", MODE_FLOAT, BITS_PER_UNIT*12, 12, 12, TFmode, VOIDmo
DEF_MACHMODE (TFmode, "TF", MODE_FLOAT, BITS_PER_UNIT*16, 16, 16, VOIDmode, VOIDmode)
/* Complex modes. */
-DEF_MACHMODE (QCmode, "QC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*2, 2, 1, HCmode, VOIDmode)
-DEF_MACHMODE (HCmode, "HC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*4, 4, 2, SCmode, VOIDmode)
-DEF_MACHMODE (SCmode, "SC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*8, 8, 4, DCmode, VOIDmode)
-DEF_MACHMODE (DCmode, "DC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*16, 16, 8, XCmode, VOIDmode)
-DEF_MACHMODE (XCmode, "XC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*24, 24, 12, TCmode, VOIDmode)
-DEF_MACHMODE (TCmode, "TC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*32, 32, 16, VOIDmode, VOIDmode)
-
-DEF_MACHMODE (CQImode, "CQI", MODE_COMPLEX_INT, BITS_PER_UNIT*2, 2, 1, CHImode, VOIDmode)
-DEF_MACHMODE (CHImode, "CHI", MODE_COMPLEX_INT, BITS_PER_UNIT*4, 4, 2, CSImode, VOIDmode)
-DEF_MACHMODE (CSImode, "CSI", MODE_COMPLEX_INT, BITS_PER_UNIT*8, 8, 4, CDImode, VOIDmode)
-DEF_MACHMODE (CDImode, "CDI", MODE_COMPLEX_INT, BITS_PER_UNIT*16, 16, 8, CTImode, VOIDmode)
-DEF_MACHMODE (CTImode, "CTI", MODE_COMPLEX_INT, BITS_PER_UNIT*32, 32, 16, COImode, VOIDmode)
-DEF_MACHMODE (COImode, "COI", MODE_COMPLEX_INT, BITS_PER_UNIT*64, 64, 32, VOIDmode, VOIDmode)
+DEF_MACHMODE (QCmode, "QC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*2, 2, 1, HCmode, QFmode)
+DEF_MACHMODE (HCmode, "HC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*4, 4, 2, SCmode, HFmode)
+DEF_MACHMODE (SCmode, "SC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*8, 8, 4, DCmode, SFmode)
+DEF_MACHMODE (DCmode, "DC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*16, 16, 8, XCmode, DFmode)
+DEF_MACHMODE (XCmode, "XC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*24, 24, 12, TCmode, XFmode)
+DEF_MACHMODE (TCmode, "TC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*32, 32, 16, VOIDmode, TFmode)
+
+DEF_MACHMODE (CQImode, "CQI", MODE_COMPLEX_INT, BITS_PER_UNIT*2, 2, 1, CHImode, QImode)
+DEF_MACHMODE (CHImode, "CHI", MODE_COMPLEX_INT, BITS_PER_UNIT*4, 4, 2, CSImode, HImode)
+DEF_MACHMODE (CSImode, "CSI", MODE_COMPLEX_INT, BITS_PER_UNIT*8, 8, 4, CDImode, SImode)
+DEF_MACHMODE (CDImode, "CDI", MODE_COMPLEX_INT, BITS_PER_UNIT*16, 16, 8, CTImode, DImode)
+DEF_MACHMODE (CTImode, "CTI", MODE_COMPLEX_INT, BITS_PER_UNIT*32, 32, 16, COImode, TImode)
+DEF_MACHMODE (COImode, "COI", MODE_COMPLEX_INT, BITS_PER_UNIT*64, 64, 32, VOIDmode, OImode)
/* Vector modes. */
/* There are no V1xx vector modes. These are equivalent to normal