Commit 4d4cbc0e by Aldy Hernandez Committed by Aldy Hernandez

config.gcc: Add support for --enable-e500_double.

	* config.gcc: Add support for --enable-e500_double.

	* config/rs6000/e500-double.h: New file.

	* config/rs6000/rs6000.h: Define TARGET_E500_SINGLE and
	TARGET_E500_DOUBLE.

	* config/rs6000/eabi.h: Define TARGET_E500_SINGLE and
	TARGET_E500_DOUBLE.

	* config/rs6000/linuxspe.h: Same.

	* doc/invoke.texi (Option Summary): Document new options for
	mfloat-gprs.
	(RS/6000 and PowerPC Options): Same.

	* config/rs6000/rs6000.c (rs6000_parse_float_gprs_option): New
	function.
	(rs6000_override_options): Use it.  Use
	SUB3TARGET_OVERRIDE_OPTIONS.
	Add 8548 to processor_target_table.
	(rs6000_legitimate_address): Handle e500 doubles.
	(rs6000_legitimize_address): Same.
	(rs6000_legitimize_reload_address): Same.
	(rs6000_hard_regno_nregs): Same.
	(spe_func_has_64bit_regs_p): Same.
	(emit_frame_save): Same.
	(gen_frame_mem_offset): Same.
	(rs6000_dwarf_register_span): Same.
	(rs6000_generate_compare): Same.
	(easy_fp_constant): Same.
	(legitimate_offset_address_p): Same.

	* config/rs6000/spe.md: (cmdfeq_gpr): New.
	(tstdfeq_gpr): New.
	(cmpdfgt_gpr): New.
	(tstdfgt_gpr): New.
	(tstdfgt_gpr): New.
	(cmpdflt_gpr): New.
	(tstdflt_gpr): New.
	Add new constants.

From-SVN: r89416
parent cbf52bfa
2004-10-21 Aldy Hernandez <aldyh@redhat.com>
* config.gcc: Add support for --enable-e500_double.
* config/rs6000/e500-double.h: New file.
* config/rs6000/rs6000.h: Define TARGET_E500_SINGLE and
TARGET_E500_DOUBLE.
* config/rs6000/eabi.h: Define TARGET_E500_SINGLE and
TARGET_E500_DOUBLE.
* config/rs6000/linuxspe.h: Same.
* doc/invoke.texi (Option Summary): Document new options for
mfloat-gprs.
(RS/6000 and PowerPC Options): Same.
* config/rs6000/rs6000.c (rs6000_parse_float_gprs_option): New
function.
(rs6000_override_options): Use it. Use
SUB3TARGET_OVERRIDE_OPTIONS.
Add 8548 to processor_target_table.
(rs6000_legitimate_address): Handle e500 doubles.
(rs6000_legitimize_address): Same.
(rs6000_legitimize_reload_address): Same.
(rs6000_hard_regno_nregs): Same.
(spe_func_has_64bit_regs_p): Same.
(emit_frame_save): Same.
(gen_frame_mem_offset): Same.
(rs6000_dwarf_register_span): Same.
(rs6000_generate_compare): Same.
(easy_fp_constant): Same.
(legitimate_offset_address_p): Same.
* config/rs6000/spe.md: (cmdfeq_gpr): New.
(tstdfeq_gpr): New.
(cmpdfgt_gpr): New.
(tstdfgt_gpr): New.
(tstdfgt_gpr): New.
(cmpdflt_gpr): New.
(tstdflt_gpr): New.
Add new constants.
2004-10-21 Giovanni Bajo <giovannibajo@gcc.gnu.org> 2004-10-21 Giovanni Bajo <giovannibajo@gcc.gnu.org>
* config/arc/lib1funcs.asm (___umulsidi3): Fix typo. * config/arc/lib1funcs.asm (___umulsidi3): Fix typo.
......
...@@ -2665,6 +2665,11 @@ fi ...@@ -2665,6 +2665,11 @@ fi
c_target_objs="${c_target_objs} rs6000-c.o" c_target_objs="${c_target_objs} rs6000-c.o"
cxx_target_objs="${cxx_target_objs} rs6000-c.o" cxx_target_objs="${cxx_target_objs} rs6000-c.o"
tmake_file="rs6000/t-rs6000 ${tmake_file}" tmake_file="rs6000/t-rs6000 ${tmake_file}"
if test x$enable_e500_double = xyes
then
tm_file="$tm_file rs6000/e500-double.h"
fi
;; ;;
sparc*-*-*) sparc*-*-*)
......
/* Target definitions for E500 with double precision FP.
Copyright (C) 2004 Free Software Foundation, Inc.
Contributed by Aldy Hernandez (aldyh@redhat.com).
This file is part of GCC.
GCC 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.
GCC 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 GCC; see the file COPYING. If not, write to the
Free Software Foundation, 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA. */
#undef SUB3TARGET_OVERRIDE_OPTIONS
#define SUB3TARGET_OVERRIDE_OPTIONS \
if (rs6000_float_gprs_string == NULL) \
rs6000_float_gprs = 2;
...@@ -49,9 +49,13 @@ ...@@ -49,9 +49,13 @@
#undef TARGET_E500 #undef TARGET_E500
#undef TARGET_ISEL #undef TARGET_ISEL
#undef TARGET_FPRS #undef TARGET_FPRS
#undef TARGET_E500_SINGLE
#undef TARGET_E500_DOUBLE
#define TARGET_SPE_ABI rs6000_spe_abi #define TARGET_SPE_ABI rs6000_spe_abi
#define TARGET_SPE rs6000_spe #define TARGET_SPE rs6000_spe
#define TARGET_E500 (rs6000_cpu == PROCESSOR_PPC8540) #define TARGET_E500 (rs6000_cpu == PROCESSOR_PPC8540)
#define TARGET_ISEL rs6000_isel #define TARGET_ISEL rs6000_isel
#define TARGET_FPRS (!rs6000_float_gprs) #define TARGET_FPRS (rs6000_float_gprs == 0)
#define TARGET_E500_SINGLE (TARGET_HARD_FLOAT && rs6000_float_gprs == 1)
#define TARGET_E500_DOUBLE (TARGET_HARD_FLOAT && rs6000_float_gprs == 2)
...@@ -32,12 +32,16 @@ ...@@ -32,12 +32,16 @@
#undef TARGET_E500 #undef TARGET_E500
#undef TARGET_ISEL #undef TARGET_ISEL
#undef TARGET_FPRS #undef TARGET_FPRS
#undef TARGET_E500_SINGLE
#undef TARGET_E500_DOUBLE
#define TARGET_SPE_ABI rs6000_spe_abi #define TARGET_SPE_ABI rs6000_spe_abi
#define TARGET_SPE rs6000_spe #define TARGET_SPE rs6000_spe
#define TARGET_E500 (rs6000_cpu == PROCESSOR_PPC8540) #define TARGET_E500 (rs6000_cpu == PROCESSOR_PPC8540)
#define TARGET_ISEL rs6000_isel #define TARGET_ISEL rs6000_isel
#define TARGET_FPRS (!rs6000_float_gprs) #define TARGET_FPRS (rs6000_float_gprs == 0)
#define TARGET_E500_SINGLE (TARGET_HARD_FLOAT && rs6000_float_gprs == 1)
#define TARGET_E500_DOUBLE (TARGET_HARD_FLOAT && rs6000_float_gprs == 2)
#undef SUBSUBTARGET_OVERRIDE_OPTIONS #undef SUBSUBTARGET_OVERRIDE_OPTIONS
#define SUBSUBTARGET_OVERRIDE_OPTIONS \ #define SUBSUBTARGET_OVERRIDE_OPTIONS \
......
...@@ -723,6 +723,7 @@ static void rs6000_parse_abi_options (void); ...@@ -723,6 +723,7 @@ static void rs6000_parse_abi_options (void);
static void rs6000_parse_alignment_option (void); static void rs6000_parse_alignment_option (void);
static void rs6000_parse_tls_size_option (void); static void rs6000_parse_tls_size_option (void);
static void rs6000_parse_yes_no_option (const char *, const char *, int *); static void rs6000_parse_yes_no_option (const char *, const char *, int *);
static void rs6000_parse_float_gprs_option (void);
static int first_altivec_reg_to_save (void); static int first_altivec_reg_to_save (void);
static unsigned int compute_vrsave_mask (void); static unsigned int compute_vrsave_mask (void);
static void compute_save_world_info(rs6000_stack_t *info_ptr); static void compute_save_world_info(rs6000_stack_t *info_ptr);
...@@ -1119,6 +1120,8 @@ rs6000_override_options (const char *default_cpu) ...@@ -1119,6 +1120,8 @@ rs6000_override_options (const char *default_cpu)
{"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT}, {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
{"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT}, {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
{"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_PPC_GFXOPT}, {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
/* 8548 has a dummy entry for now. */
{"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
{"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT}, {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
{"970", PROCESSOR_POWER4, {"970", PROCESSOR_POWER4,
POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64}, POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
...@@ -1292,14 +1295,14 @@ rs6000_override_options (const char *default_cpu) ...@@ -1292,14 +1295,14 @@ rs6000_override_options (const char *default_cpu)
/* Handle -malign-XXXXX option. */ /* Handle -malign-XXXXX option. */
rs6000_parse_alignment_option (); rs6000_parse_alignment_option ();
rs6000_parse_float_gprs_option ();
/* Handle generic -mFOO=YES/NO options. */ /* Handle generic -mFOO=YES/NO options. */
rs6000_parse_yes_no_option ("vrsave", rs6000_altivec_vrsave_string, rs6000_parse_yes_no_option ("vrsave", rs6000_altivec_vrsave_string,
&rs6000_altivec_vrsave); &rs6000_altivec_vrsave);
rs6000_parse_yes_no_option ("isel", rs6000_isel_string, rs6000_parse_yes_no_option ("isel", rs6000_isel_string,
&rs6000_isel); &rs6000_isel);
rs6000_parse_yes_no_option ("spe", rs6000_spe_string, &rs6000_spe); rs6000_parse_yes_no_option ("spe", rs6000_spe_string, &rs6000_spe);
rs6000_parse_yes_no_option ("float-gprs", rs6000_float_gprs_string,
&rs6000_float_gprs);
/* Handle -mtls-size option. */ /* Handle -mtls-size option. */
rs6000_parse_tls_size_option (); rs6000_parse_tls_size_option ();
...@@ -1310,6 +1313,9 @@ rs6000_override_options (const char *default_cpu) ...@@ -1310,6 +1313,9 @@ rs6000_override_options (const char *default_cpu)
#ifdef SUBSUBTARGET_OVERRIDE_OPTIONS #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
SUBSUBTARGET_OVERRIDE_OPTIONS; SUBSUBTARGET_OVERRIDE_OPTIONS;
#endif #endif
#ifdef SUB3TARGET_OVERRIDE_OPTIONS
SUB3TARGET_OVERRIDE_OPTIONS;
#endif
if (TARGET_E500) if (TARGET_E500)
{ {
...@@ -1622,6 +1628,23 @@ rs6000_parse_abi_options (void) ...@@ -1622,6 +1628,23 @@ rs6000_parse_abi_options (void)
error ("unknown ABI specified: '%s'", rs6000_abi_string); error ("unknown ABI specified: '%s'", rs6000_abi_string);
} }
/* Handle -mfloat-gprs= options. */
static void
rs6000_parse_float_gprs_option (void)
{
if (rs6000_float_gprs_string == 0)
return;
else if (! strcmp (rs6000_float_gprs_string, "yes")
|| ! strcmp (rs6000_float_gprs_string, "single"))
rs6000_float_gprs = 1;
else if (! strcmp (rs6000_float_gprs_string, "double"))
rs6000_float_gprs = 2;
else if (! strcmp (rs6000_float_gprs_string, "no"))
rs6000_float_gprs = 0;
else
error ("invalid option for -mfloat-gprs");
}
/* Handle -malign-XXXXXX options. */ /* Handle -malign-XXXXXX options. */
static void static void
rs6000_parse_alignment_option (void) rs6000_parse_alignment_option (void)
...@@ -2163,7 +2186,7 @@ easy_fp_constant (rtx op, enum machine_mode mode) ...@@ -2163,7 +2186,7 @@ easy_fp_constant (rtx op, enum machine_mode mode)
return 0; return 0;
/* Consider all constants with -msoft-float to be easy. */ /* Consider all constants with -msoft-float to be easy. */
if ((TARGET_SOFT_FLOAT || !TARGET_FPRS) if ((TARGET_SOFT_FLOAT || TARGET_E500_SINGLE)
&& mode != DImode) && mode != DImode)
return 1; return 1;
...@@ -2197,6 +2220,9 @@ easy_fp_constant (rtx op, enum machine_mode mode) ...@@ -2197,6 +2220,9 @@ easy_fp_constant (rtx op, enum machine_mode mode)
long k[2]; long k[2];
REAL_VALUE_TYPE rv; REAL_VALUE_TYPE rv;
if (TARGET_E500_DOUBLE)
return 0;
REAL_VALUE_FROM_CONST_DOUBLE (rv, op); REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
REAL_VALUE_TO_TARGET_DOUBLE (rv, k); REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
...@@ -3173,6 +3199,9 @@ rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict) ...@@ -3173,6 +3199,9 @@ rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
return SPE_CONST_OFFSET_OK (offset); return SPE_CONST_OFFSET_OK (offset);
case DFmode: case DFmode:
if (TARGET_E500_DOUBLE)
return SPE_CONST_OFFSET_OK (offset);
case DImode: case DImode:
if (mode == DFmode || !TARGET_POWERPC64) if (mode == DFmode || !TARGET_POWERPC64)
extra = 4; extra = 4;
...@@ -3325,7 +3354,7 @@ rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, ...@@ -3325,7 +3354,7 @@ rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
&& GET_MODE_NUNITS (mode) == 1 && GET_MODE_NUNITS (mode) == 1
&& ((TARGET_HARD_FLOAT && TARGET_FPRS) && ((TARGET_HARD_FLOAT && TARGET_FPRS)
|| TARGET_POWERPC64 || TARGET_POWERPC64
|| (mode != DFmode && mode != TFmode)) || ((mode != DFmode || TARGET_E500_DOUBLE) && mode != TFmode))
&& (TARGET_POWERPC64 || mode != DImode) && (TARGET_POWERPC64 || mode != DImode)
&& mode != TImode) && mode != TImode)
{ {
...@@ -3344,7 +3373,8 @@ rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, ...@@ -3344,7 +3373,8 @@ rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
reg = force_reg (Pmode, x); reg = force_reg (Pmode, x);
return reg; return reg;
} }
else if (SPE_VECTOR_MODE (mode)) else if (SPE_VECTOR_MODE (mode)
|| (TARGET_E500_DOUBLE && mode == DFmode))
{ {
/* We accept [reg + reg] and [reg + OFFSET]. */ /* We accept [reg + reg] and [reg + OFFSET]. */
...@@ -3388,7 +3418,8 @@ rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, ...@@ -3388,7 +3418,8 @@ rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
&& GET_CODE (x) != CONST_INT && GET_CODE (x) != CONST_INT
&& GET_CODE (x) != CONST_DOUBLE && GET_CODE (x) != CONST_DOUBLE
&& CONSTANT_P (x) && CONSTANT_P (x)
&& ((TARGET_HARD_FLOAT && TARGET_FPRS) || mode != DFmode) && ((TARGET_HARD_FLOAT && TARGET_FPRS)
|| (mode != DFmode || TARGET_E500_DOUBLE))
&& mode != DImode && mode != DImode
&& mode != TImode) && mode != TImode)
{ {
...@@ -3735,6 +3766,7 @@ rs6000_legitimize_reload_address (rtx x, enum machine_mode mode, ...@@ -3735,6 +3766,7 @@ rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
&& REG_MODE_OK_FOR_BASE_P (XEXP (x, 0), mode) && REG_MODE_OK_FOR_BASE_P (XEXP (x, 0), mode)
&& GET_CODE (XEXP (x, 1)) == CONST_INT && GET_CODE (XEXP (x, 1)) == CONST_INT
&& !SPE_VECTOR_MODE (mode) && !SPE_VECTOR_MODE (mode)
&& !(TARGET_E500_DOUBLE && mode == DFmode)
&& !ALTIVEC_VECTOR_MODE (mode)) && !ALTIVEC_VECTOR_MODE (mode))
{ {
HOST_WIDE_INT val = INTVAL (XEXP (x, 1)); HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
...@@ -3838,6 +3870,7 @@ rs6000_legitimate_address (enum machine_mode mode, rtx x, int reg_ok_strict) ...@@ -3838,6 +3870,7 @@ rs6000_legitimate_address (enum machine_mode mode, rtx x, int reg_ok_strict)
if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC) if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
&& !ALTIVEC_VECTOR_MODE (mode) && !ALTIVEC_VECTOR_MODE (mode)
&& !SPE_VECTOR_MODE (mode) && !SPE_VECTOR_MODE (mode)
&& !(TARGET_E500_DOUBLE && mode == DFmode)
&& TARGET_UPDATE && TARGET_UPDATE
&& legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)) && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
return 1; return 1;
...@@ -3859,7 +3892,7 @@ rs6000_legitimate_address (enum machine_mode mode, rtx x, int reg_ok_strict) ...@@ -3859,7 +3892,7 @@ rs6000_legitimate_address (enum machine_mode mode, rtx x, int reg_ok_strict)
&& mode != TFmode && mode != TFmode
&& ((TARGET_HARD_FLOAT && TARGET_FPRS) && ((TARGET_HARD_FLOAT && TARGET_FPRS)
|| TARGET_POWERPC64 || TARGET_POWERPC64
|| (mode != DFmode && mode != TFmode)) || ((mode != DFmode || TARGET_E500_DOUBLE) && mode != TFmode))
&& (TARGET_POWERPC64 || mode != DImode) && (TARGET_POWERPC64 || mode != DImode)
&& legitimate_indexed_address_p (x, reg_ok_strict)) && legitimate_indexed_address_p (x, reg_ok_strict))
return 1; return 1;
...@@ -3924,6 +3957,9 @@ rs6000_hard_regno_nregs (int regno, enum machine_mode mode) ...@@ -3924,6 +3957,9 @@ rs6000_hard_regno_nregs (int regno, enum machine_mode mode)
if (FP_REGNO_P (regno)) if (FP_REGNO_P (regno))
return (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD; return (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
if (TARGET_E500_DOUBLE && mode == DFmode)
return 1;
if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode)) if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
return (GET_MODE_SIZE (mode) + UNITS_PER_SPE_WORD - 1) / UNITS_PER_SPE_WORD; return (GET_MODE_SIZE (mode) + UNITS_PER_SPE_WORD - 1) / UNITS_PER_SPE_WORD;
...@@ -10864,6 +10900,10 @@ rs6000_generate_compare (enum rtx_code code) ...@@ -10864,6 +10900,10 @@ rs6000_generate_compare (enum rtx_code code)
&& rs6000_compare_fp_p) && rs6000_compare_fp_p)
{ {
rtx cmp, or1, or2, or_result, compare_result2; rtx cmp, or1, or2, or_result, compare_result2;
enum machine_mode op_mode = GET_MODE (rs6000_compare_op0);
if (op_mode == VOIDmode)
op_mode = GET_MODE (rs6000_compare_op1);
/* Note: The E500 comparison instructions set the GT bit (x + /* Note: The E500 comparison instructions set the GT bit (x +
1), on success. This explains the mess. */ 1), on success. This explains the mess. */
...@@ -10871,28 +10911,52 @@ rs6000_generate_compare (enum rtx_code code) ...@@ -10871,28 +10911,52 @@ rs6000_generate_compare (enum rtx_code code)
switch (code) switch (code)
{ {
case EQ: case UNEQ: case NE: case LTGT: case EQ: case UNEQ: case NE: case LTGT:
cmp = flag_finite_math_only if (op_mode == SFmode)
? gen_tstsfeq_gpr (compare_result, rs6000_compare_op0, cmp = flag_finite_math_only
rs6000_compare_op1) ? gen_tstsfeq_gpr (compare_result, rs6000_compare_op0,
: gen_cmpsfeq_gpr (compare_result, rs6000_compare_op0, rs6000_compare_op1)
rs6000_compare_op1); : gen_cmpsfeq_gpr (compare_result, rs6000_compare_op0,
rs6000_compare_op1);
else if (op_mode == DFmode)
cmp = flag_finite_math_only
? gen_tstdfeq_gpr (compare_result, rs6000_compare_op0,
rs6000_compare_op1)
: gen_cmpdfeq_gpr (compare_result, rs6000_compare_op0,
rs6000_compare_op1);
else abort ();
break; break;
case GT: case GTU: case UNGT: case UNGE: case GE: case GEU: case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
cmp = flag_finite_math_only if (op_mode == SFmode)
? gen_tstsfgt_gpr (compare_result, rs6000_compare_op0, cmp = flag_finite_math_only
rs6000_compare_op1) ? gen_tstsfgt_gpr (compare_result, rs6000_compare_op0,
: gen_cmpsfgt_gpr (compare_result, rs6000_compare_op0, rs6000_compare_op1)
rs6000_compare_op1); : gen_cmpsfgt_gpr (compare_result, rs6000_compare_op0,
rs6000_compare_op1);
else if (op_mode == DFmode)
cmp = flag_finite_math_only
? gen_tstdfgt_gpr (compare_result, rs6000_compare_op0,
rs6000_compare_op1)
: gen_cmpdfgt_gpr (compare_result, rs6000_compare_op0,
rs6000_compare_op1);
else abort ();
break; break;
case LT: case LTU: case UNLT: case UNLE: case LE: case LEU: case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
cmp = flag_finite_math_only if (op_mode == SFmode)
? gen_tstsflt_gpr (compare_result, rs6000_compare_op0, cmp = flag_finite_math_only
rs6000_compare_op1) ? gen_tstsflt_gpr (compare_result, rs6000_compare_op0,
: gen_cmpsflt_gpr (compare_result, rs6000_compare_op0, rs6000_compare_op1)
rs6000_compare_op1); : gen_cmpsflt_gpr (compare_result, rs6000_compare_op0,
rs6000_compare_op1);
else if (op_mode == DFmode)
cmp = flag_finite_math_only
? gen_tstdflt_gpr (compare_result, rs6000_compare_op0,
rs6000_compare_op1)
: gen_cmpdflt_gpr (compare_result, rs6000_compare_op0,
rs6000_compare_op1);
else abort ();
break; break;
default: default:
abort (); abort ();
} }
/* Synthesize LE and GE from LT/GT || EQ. */ /* Synthesize LE and GE from LT/GT || EQ. */
...@@ -10915,11 +10979,19 @@ rs6000_generate_compare (enum rtx_code code) ...@@ -10915,11 +10979,19 @@ rs6000_generate_compare (enum rtx_code code)
compare_result2 = gen_reg_rtx (CCFPmode); compare_result2 = gen_reg_rtx (CCFPmode);
/* Do the EQ. */ /* Do the EQ. */
cmp = flag_finite_math_only if (op_mode == SFmode)
? gen_tstsfeq_gpr (compare_result2, rs6000_compare_op0, cmp = flag_finite_math_only
rs6000_compare_op1) ? gen_tstsfeq_gpr (compare_result2, rs6000_compare_op0,
: gen_cmpsfeq_gpr (compare_result2, rs6000_compare_op0, rs6000_compare_op1)
rs6000_compare_op1); : gen_cmpsfeq_gpr (compare_result2, rs6000_compare_op0,
rs6000_compare_op1);
else if (op_mode == DFmode)
cmp = flag_finite_math_only
? gen_tstdfeq_gpr (compare_result2, rs6000_compare_op0,
rs6000_compare_op1)
: gen_cmpdfeq_gpr (compare_result2, rs6000_compare_op0,
rs6000_compare_op1);
else abort ();
emit_insn (cmp); emit_insn (cmp);
or1 = gen_rtx_GT (SImode, compare_result, const0_rtx); or1 = gen_rtx_GT (SImode, compare_result, const0_rtx);
...@@ -13289,6 +13361,7 @@ emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode, ...@@ -13289,6 +13361,7 @@ emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
/* Some cases that need register indexed addressing. */ /* Some cases that need register indexed addressing. */
if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode)) if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
|| (TARGET_E500_DOUBLE && mode == DFmode)
|| (TARGET_SPE_ABI || (TARGET_SPE_ABI
&& SPE_VECTOR_MODE (mode) && SPE_VECTOR_MODE (mode)
&& !SPE_CONST_OFFSET_OK (offset))) && !SPE_CONST_OFFSET_OK (offset)))
...@@ -13328,7 +13401,8 @@ gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset) ...@@ -13328,7 +13401,8 @@ gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
int_rtx = GEN_INT (offset); int_rtx = GEN_INT (offset);
if (TARGET_SPE_ABI && SPE_VECTOR_MODE (mode)) if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
|| (TARGET_E500_DOUBLE && mode == DFmode))
{ {
offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH); offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
emit_move_insn (offset_rtx, int_rtx); emit_move_insn (offset_rtx, int_rtx);
...@@ -18082,7 +18156,11 @@ rs6000_dwarf_register_span (rtx reg) ...@@ -18082,7 +18156,11 @@ rs6000_dwarf_register_span (rtx reg)
{ {
unsigned regno; unsigned regno;
if (!TARGET_SPE || !SPE_VECTOR_MODE (GET_MODE (reg))) if (TARGET_SPE
&& (SPE_VECTOR_MODE (GET_MODE (reg))
|| (TARGET_E500_DOUBLE && GET_MODE (reg) == DFmode)))
;
else
return NULL_RTX; return NULL_RTX;
regno = REGNO (reg); regno = REGNO (reg);
......
...@@ -568,6 +568,8 @@ extern const char *rs6000_warn_altivec_long_switch; ...@@ -568,6 +568,8 @@ extern const char *rs6000_warn_altivec_long_switch;
#define TARGET_E500 0 #define TARGET_E500 0
#define TARGET_ISEL 0 #define TARGET_ISEL 0
#define TARGET_FPRS 1 #define TARGET_FPRS 1
#define TARGET_E500_SINGLE 0
#define TARGET_E500_DOUBLE 0
/* Sometimes certain combinations of command options do not make sense /* Sometimes certain combinations of command options do not make sense
on a particular target machine. You can define a macro on a particular target machine. You can define a macro
......
...@@ -21,7 +21,15 @@ ...@@ -21,7 +21,15 @@
(define_constants (define_constants
[(SPE_ACC_REGNO 111) [(SPE_ACC_REGNO 111)
(SPEFSCR_REGNO 112)]) (SPEFSCR_REGNO 112)
(CMPDFEQ_GPR 1006)
(TSTDFEQ_GPR 1007)
(CMPDFGT_GPR 1008)
(TSTDFGT_GPR 1009)
(CMPDFLT_GPR 1010)
(TSTDFLT_GPR 1011)
])
(define_insn "*negsf2_gpr" (define_insn "*negsf2_gpr"
[(set (match_operand:SF 0 "gpc_reg_operand" "=r") [(set (match_operand:SF 0 "gpc_reg_operand" "=r")
...@@ -2532,3 +2540,65 @@ ...@@ -2532,3 +2540,65 @@
"TARGET_HARD_FLOAT && !TARGET_FPRS && flag_unsafe_math_optimizations" "TARGET_HARD_FLOAT && !TARGET_FPRS && flag_unsafe_math_optimizations"
"efststlt %0,%1,%2" "efststlt %0,%1,%2"
[(set_attr "type" "veccmpsimple")]) [(set_attr "type" "veccmpsimple")])
;; Same thing, but for double-precision.
(define_insn "cmpdfeq_gpr"
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
(unspec:CCFP
[(compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "r")
(match_operand:DF 2 "gpc_reg_operand" "r"))]
CMPDFEQ_GPR))]
"TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && !flag_unsafe_math_optimizations"
"efdcmpeq %0,%1,%2"
[(set_attr "type" "veccmp")])
(define_insn "tstdfeq_gpr"
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
(unspec:CCFP
[(compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "r")
(match_operand:DF 2 "gpc_reg_operand" "r"))]
TSTDFEQ_GPR))]
"TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && flag_unsafe_math_optimizations"
"efdtsteq %0,%1,%2"
[(set_attr "type" "veccmpsimple")])
(define_insn "cmpdfgt_gpr"
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
(unspec:CCFP
[(compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "r")
(match_operand:DF 2 "gpc_reg_operand" "r"))]
CMPDFGT_GPR))]
"TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && !flag_unsafe_math_optimizations"
"efdcmpgt %0,%1,%2"
[(set_attr "type" "veccmp")])
(define_insn "tstdfgt_gpr"
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
(unspec:CCFP
[(compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "r")
(match_operand:DF 2 "gpc_reg_operand" "r"))]
TSTDFGT_GPR))]
"TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && flag_unsafe_math_optimizations"
"efdtstgt %0,%1,%2"
[(set_attr "type" "veccmpsimple")])
(define_insn "cmpdflt_gpr"
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
(unspec:CCFP
[(compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "r")
(match_operand:DF 2 "gpc_reg_operand" "r"))]
CMPDFLT_GPR))]
"TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && !flag_unsafe_math_optimizations"
"efdcmplt %0,%1,%2"
[(set_attr "type" "veccmp")])
(define_insn "tstdflt_gpr"
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
(unspec:CCFP
[(compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "r")
(match_operand:DF 2 "gpc_reg_operand" "r"))]
TSTDFLT_GPR))]
"TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && flag_unsafe_math_optimizations"
"efdtstlt %0,%1,%2"
[(set_attr "type" "veccmpsimple")])
...@@ -616,7 +616,7 @@ See RS/6000 and PowerPC Options. ...@@ -616,7 +616,7 @@ See RS/6000 and PowerPC Options.
-mabi=spe -mabi=no-spe @gol -mabi=spe -mabi=no-spe @gol
-misel=yes -misel=no @gol -misel=yes -misel=no @gol
-mspe=yes -mspe=no @gol -mspe=yes -mspe=no @gol
-mfloat-gprs=yes -mfloat-gprs=no @gol -mfloat-gprs=yes -mfloat-gprs=no -mfloat-gprs=single -mfloat-gprs=double @gol
-mprototype -mno-prototype @gol -mprototype -mno-prototype @gol
-msim -mmvme -mads -myellowknife -memb -msdata @gol -msim -mmvme -mads -myellowknife -memb -msdata @gol
-msdata=@var{opt} -mvxworks -mwindiss -G @var{num} -pthread} -msdata=@var{opt} -mvxworks -mwindiss -G @var{num} -pthread}
...@@ -10279,12 +10279,23 @@ This switch enables or disables the generation of ISEL instructions. ...@@ -10279,12 +10279,23 @@ This switch enables or disables the generation of ISEL instructions.
This switch enables or disables the generation of SPE simd This switch enables or disables the generation of SPE simd
instructions. instructions.
@item -mfloat-gprs=@var{yes/no} @item -mfloat-gprs=@var{yes/single/double/no}
@itemx -mfloat-gprs @itemx -mfloat-gprs
@opindex mfloat-gprs @opindex mfloat-gprs
This switch enables or disables the generation of floating point This switch enables or disables the generation of floating point
operations on the general purpose registers for architectures that operations on the general purpose registers for architectures that
support it. This option is currently only available on the MPC8540. support it.
The argument @var{yes} or @var{single} enables the use of
single-precision floating point operations.
The argument @var{double} enables the use of single and
double-precision floating point operations.
The argument @var{no} disables floating point operations on the
general purpose registers.
This option is currently only available on the MPC854x.
@item -m32 @item -m32
@itemx -m64 @itemx -m64
......
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