Commit c6e6f5c1 by Richard Henderson Committed by Richard Henderson

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
parent d88e57d1
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> 2002-03-23 Richard Henderson <rth@redhat.com>
* config/sparc/sparc.c (sparc_emit_floatunsdi): New. * config/sparc/sparc.c (sparc_emit_floatunsdi): New.
......
...@@ -99,9 +99,6 @@ Boston, MA 02111-1307, USA. */ ...@@ -99,9 +99,6 @@ Boston, MA 02111-1307, USA. */
&& (FUNCTION_ARG_PADDING (MODE, TYPE) \ && (FUNCTION_ARG_PADDING (MODE, TYPE) \
== (BYTES_BIG_ENDIAN ? upward : downward))))) == (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) #define STRICT_ARGUMENT_NAMING (mips_abi != ABI_32 && mips_abi != ABI_O64)
/* A C expression that indicates when an argument must be passed by /* A C expression that indicates when an argument must be passed by
......
...@@ -50,7 +50,8 @@ extern struct rtx_def * mips16_gp_pseudo_reg PARAMS ((void)); ...@@ -50,7 +50,8 @@ extern struct rtx_def * mips16_gp_pseudo_reg PARAMS ((void));
#ifdef ASM_OUTPUT_UNDEF_FUNCTION #ifdef ASM_OUTPUT_UNDEF_FUNCTION
extern int mips_output_external_libcall PARAMS ((FILE *, const char *)); extern int mips_output_external_libcall PARAMS ((FILE *, const char *));
#endif /* ASM_OUTPUT_UNDEF_FUNCTION */ #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, extern unsigned int mips_hard_regno_nregs PARAMS ((int,
enum machine_mode)); enum machine_mode));
......
...@@ -7912,22 +7912,25 @@ mips_select_section (decl, reloc) ...@@ -7912,22 +7912,25 @@ mips_select_section (decl, reloc)
} }
} }
#ifdef MIPS_ABI_DEFAULT /* Return register to use for a function return value with VALTYPE for
function FUNC. MODE is used instead of VALTYPE for LIBCALLs. */
/* Support functions for the 64 bit ABI. */
/* Return register to use for a function return value with VALTYPE for function
FUNC. */
rtx rtx
mips_function_value (valtype, func) mips_function_value (valtype, func, mode)
tree valtype; tree valtype;
tree func ATTRIBUTE_UNUSED; tree func ATTRIBUTE_UNUSED;
enum machine_mode mode;
{ {
int reg = GP_RETURN; int reg = GP_RETURN;
enum machine_mode mode = TYPE_MODE (valtype); enum mode_class mclass;
enum mode_class mclass = GET_MODE_CLASS (mode); int unsignedp = 1;
int unsignedp = TREE_UNSIGNED (valtype);
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 /* Since we define PROMOTE_FUNCTION_RETURN, we must promote the mode
just as PROMOTE_MODE does. */ just as PROMOTE_MODE does. */
...@@ -7939,7 +7942,7 @@ mips_function_value (valtype, func) ...@@ -7939,7 +7942,7 @@ mips_function_value (valtype, func)
else if (mclass == MODE_COMPLEX_FLOAT else if (mclass == MODE_COMPLEX_FLOAT
&& GET_MODE_SIZE (mode) <= UNITS_PER_FPVALUE * 2) && 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 return gen_rtx_PARALLEL
(VOIDmode, (VOIDmode,
...@@ -7952,7 +7955,7 @@ mips_function_value (valtype, func) ...@@ -7952,7 +7955,7 @@ mips_function_value (valtype, func)
GEN_INT (GET_MODE_SIZE (cmode))))); 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_32
&& mips_abi != ABI_O64 && mips_abi != ABI_O64
&& mips_abi != ABI_EABI) && mips_abi != ABI_EABI)
...@@ -8019,7 +8022,6 @@ mips_function_value (valtype, func) ...@@ -8019,7 +8022,6 @@ mips_function_value (valtype, func)
return gen_rtx_REG (mode, reg); return gen_rtx_REG (mode, reg);
} }
#endif
/* The implementation of FUNCTION_ARG_PASS_BY_REFERENCE. Return /* The implementation of FUNCTION_ARG_PASS_BY_REFERENCE. Return
nonzero when an argument must be passed by reference. */ nonzero when an argument must be passed by reference. */
......
...@@ -2696,25 +2696,16 @@ extern struct mips_frame_info current_frame_info; ...@@ -2696,25 +2696,16 @@ extern struct mips_frame_info current_frame_info;
PROMOTE_FUNCTION_RETURN, we must promote the mode just as PROMOTE_FUNCTION_RETURN, we must promote the mode just as
PROMOTE_MODE does. */ PROMOTE_MODE does. */
#define LIBCALL_VALUE(MODE) \ #define LIBCALL_VALUE(MODE) \
gen_rtx (REG, \ mips_function_value (NULL_TREE, NULL, (MODE))
((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 how to find the value returned by a function. /* Define how to find the value returned by a function.
VALTYPE is the data type of the value (as a tree). VALTYPE is the data type of the value (as a tree).
If the precise function being called is known, FUNC is its FUNCTION_DECL; If the precise function being called is known, FUNC is its FUNCTION_DECL;
otherwise, FUNC is 0. */ 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. /* 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. On the MIPS, R2 R3 and F0 F2 are the only register thus used.
......
...@@ -65,8 +65,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA ...@@ -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, The ordering is by increasing byte size, with QI coming before HI,
HI before SI, etc. HI before SI, etc.
Eigth arg is the mode of the internal elements in a vector. Eigth arg is the mode of the internal elements in a vector or
VOIDmode if not a vector. complex, and VOIDmode if not applicable.
*/ */
/* VOIDmode is used when no mode needs to be specified, /* 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 ...@@ -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) DEF_MACHMODE (TFmode, "TF", MODE_FLOAT, BITS_PER_UNIT*16, 16, 16, VOIDmode, VOIDmode)
/* Complex modes. */ /* Complex modes. */
DEF_MACHMODE (QCmode, "QC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*2, 2, 1, HCmode, 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, VOIDmode) 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, VOIDmode) 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, VOIDmode) 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, VOIDmode) 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, VOIDmode) 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, VOIDmode) 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, VOIDmode) 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, VOIDmode) 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, VOIDmode) 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, VOIDmode) 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, VOIDmode) DEF_MACHMODE (COImode, "COI", MODE_COMPLEX_INT, BITS_PER_UNIT*64, 64, 32, VOIDmode, OImode)
/* Vector modes. */ /* Vector modes. */
/* There are no V1xx vector modes. These are equivalent to normal /* There are no V1xx vector modes. These are equivalent to normal
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment