This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[3.4-e500] add support for 8548 (1 of many)
- From: Aldy Hernandez <aldyh at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 22 Oct 2004 15:02:37 -0400
- Subject: [3.4-e500] add support for 8548 (1 of many)
Same herb, different branch.
Comitted to branch.
* 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.
(HARD_REGNO_NREGS): Handle e500 doubles.
* 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.
(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.
Index: config.gcc
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config.gcc,v
retrieving revision 1.420.2.15
diff -c -p -r1.420.2.15 config.gcc
*** config.gcc 8 Sep 2004 15:16:10 -0000 1.420.2.15
--- config.gcc 22 Oct 2004 19:00:32 -0000
*************** fi
*** 2741,2746 ****
--- 2741,2751 ----
c_target_objs="${c_target_objs} rs6000-c.o"
cxx_target_objs="${cxx_target_objs} rs6000-c.o"
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*-*-*)
Index: config/rs6000/e500-double.h
===================================================================
RCS file: config/rs6000/e500-double.h
diff -N config/rs6000/e500-double.h
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- config/rs6000/e500-double.h 22 Oct 2004 19:00:32 -0000
***************
*** 0 ****
--- 1,25 ----
+ /* 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;
Index: config/rs6000/rs6000.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.306.4.12
diff -c -p -r1.306.4.12 rs6000.h
*** config/rs6000/rs6000.h 23 Aug 2004 18:02:58 -0000 1.306.4.12
--- config/rs6000/rs6000.h 22 Oct 2004 19:00:34 -0000
*************** extern const char *rs6000_warn_altivec_l
*** 564,569 ****
--- 564,571 ----
#define TARGET_E500 0
#define TARGET_ISEL 0
#define TARGET_FPRS 1
+ #define TARGET_E500_SINGLE 0
+ #define TARGET_E500_DOUBLE 0
/* Sometimes certain combinations of command options do not make sense
on a particular target machine. You can define a macro
*************** extern const char *rs6000_warn_altivec_l
*** 1020,1025 ****
--- 1022,1028 ----
#define HARD_REGNO_NREGS(REGNO, MODE) \
(FP_REGNO_P (REGNO) \
? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD) \
+ : (TARGET_E500_DOUBLE && SPE_SIMD_REGNO_P (REGNO) && (MODE) == DFmode) ? 1 \
: (SPE_SIMD_REGNO_P (REGNO) && TARGET_SPE && SPE_VECTOR_MODE (MODE)) \
? ((GET_MODE_SIZE (MODE) + UNITS_PER_SPE_WORD - 1) / UNITS_PER_SPE_WORD) \
: ALTIVEC_REGNO_P (REGNO) \
Index: config/rs6000/eabi.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/eabi.h,v
retrieving revision 1.11
diff -c -p -r1.11 eabi.h
*** config/rs6000/eabi.h 10 Jun 2003 16:01:39 -0000 1.11
--- config/rs6000/eabi.h 22 Oct 2004 19:00:34 -0000
***************
*** 49,57 ****
#undef TARGET_E500
#undef TARGET_ISEL
#undef TARGET_FPRS
#define TARGET_SPE_ABI rs6000_spe_abi
#define TARGET_SPE rs6000_spe
#define TARGET_E500 (rs6000_cpu == PROCESSOR_PPC8540)
#define TARGET_ISEL rs6000_isel
! #define TARGET_FPRS (!rs6000_float_gprs)
--- 49,61 ----
#undef TARGET_E500
#undef TARGET_ISEL
#undef TARGET_FPRS
+ #undef TARGET_E500_SINGLE
+ #undef TARGET_E500_DOUBLE
#define TARGET_SPE_ABI rs6000_spe_abi
#define TARGET_SPE rs6000_spe
#define TARGET_E500 (rs6000_cpu == PROCESSOR_PPC8540)
#define TARGET_ISEL rs6000_isel
! #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)
Index: config/rs6000/linuxspe.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/linuxspe.h,v
retrieving revision 1.2
diff -c -p -r1.2 linuxspe.h
*** config/rs6000/linuxspe.h 5 Oct 2003 22:49:29 -0000 1.2
--- config/rs6000/linuxspe.h 22 Oct 2004 19:00:34 -0000
***************
*** 32,43 ****
#undef TARGET_E500
#undef TARGET_ISEL
#undef TARGET_FPRS
#define TARGET_SPE_ABI rs6000_spe_abi
#define TARGET_SPE rs6000_spe
#define TARGET_E500 (rs6000_cpu == PROCESSOR_PPC8540)
#define TARGET_ISEL rs6000_isel
! #define TARGET_FPRS (!rs6000_float_gprs)
#undef SUBSUBTARGET_OVERRIDE_OPTIONS
#define SUBSUBTARGET_OVERRIDE_OPTIONS \
--- 32,47 ----
#undef TARGET_E500
#undef TARGET_ISEL
#undef TARGET_FPRS
+ #undef TARGET_E500_SINGLE
+ #undef TARGET_E500_DOUBLE
#define TARGET_SPE_ABI rs6000_spe_abi
#define TARGET_SPE rs6000_spe
#define TARGET_E500 (rs6000_cpu == PROCESSOR_PPC8540)
#define TARGET_ISEL rs6000_isel
! #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
#define SUBSUBTARGET_OVERRIDE_OPTIONS \
Index: config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.576.2.32
diff -c -p -r1.576.2.32 rs6000.c
*** config/rs6000/rs6000.c 9 Sep 2004 00:25:44 -0000 1.576.2.32
--- config/rs6000/rs6000.c 22 Oct 2004 19:00:41 -0000
*************** static void rs6000_parse_abi_options (vo
*** 396,401 ****
--- 396,402 ----
static void rs6000_parse_alignment_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_float_gprs_option (void);
static int first_altivec_reg_to_save (void);
static unsigned int compute_vrsave_mask (void);
static void is_altivec_return_reg (rtx, void *);
*************** rs6000_override_options (const char *def
*** 699,704 ****
--- 700,707 ----
{"821", 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},
+ /* 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},
{"970", PROCESSOR_POWER4,
POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
*************** rs6000_override_options (const char *def
*** 869,882 ****
/* Handle -malign-XXXXX option. */
rs6000_parse_alignment_option ();
/* Handle generic -mFOO=YES/NO options. */
rs6000_parse_yes_no_option ("vrsave", rs6000_altivec_vrsave_string,
&rs6000_altivec_vrsave);
rs6000_parse_yes_no_option ("isel", rs6000_isel_string,
&rs6000_isel);
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. */
rs6000_parse_tls_size_option ();
--- 872,885 ----
/* Handle -malign-XXXXX option. */
rs6000_parse_alignment_option ();
+ rs6000_parse_float_gprs_option ();
+
/* Handle generic -mFOO=YES/NO options. */
rs6000_parse_yes_no_option ("vrsave", rs6000_altivec_vrsave_string,
&rs6000_altivec_vrsave);
rs6000_parse_yes_no_option ("isel", rs6000_isel_string,
&rs6000_isel);
rs6000_parse_yes_no_option ("spe", rs6000_spe_string, &rs6000_spe);
/* Handle -mtls-size option. */
rs6000_parse_tls_size_option ();
*************** rs6000_override_options (const char *def
*** 887,892 ****
--- 890,898 ----
#ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
SUBSUBTARGET_OVERRIDE_OPTIONS;
#endif
+ #ifdef SUB3TARGET_OVERRIDE_OPTIONS
+ SUB3TARGET_OVERRIDE_OPTIONS;
+ #endif
if (TARGET_E500)
{
*************** rs6000_parse_abi_options (void)
*** 1085,1090 ****
--- 1091,1113 ----
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. */
static void
rs6000_parse_alignment_option (void)
*************** easy_fp_constant (rtx op, enum machine_m
*** 1615,1621 ****
return 0;
/* Consider all constants with -msoft-float to be easy. */
! if ((TARGET_SOFT_FLOAT || !TARGET_FPRS)
&& mode != DImode)
return 1;
--- 1638,1644 ----
return 0;
/* Consider all constants with -msoft-float to be easy. */
! if ((TARGET_SOFT_FLOAT || TARGET_E500_SINGLE)
&& mode != DImode)
return 1;
*************** easy_fp_constant (rtx op, enum machine_m
*** 1649,1654 ****
--- 1672,1680 ----
long k[2];
REAL_VALUE_TYPE rv;
+ if (TARGET_E500_DOUBLE)
+ return 0;
+
REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
*************** legitimate_offset_address_p (enum machin
*** 2656,2661 ****
--- 2682,2690 ----
return SPE_CONST_OFFSET_OK (offset);
case DFmode:
+ if (TARGET_E500_DOUBLE)
+ return SPE_CONST_OFFSET_OK (offset);
+
case DImode:
/* Both DFmode and DImode may end up in gprs. If gprs are 32-bit,
then we need to load/store at both offset and offset+4. */
*************** rs6000_legitimize_address (rtx x, rtx ol
*** 2806,2812 ****
&& GET_MODE_NUNITS (mode) == 1
&& ((TARGET_HARD_FLOAT && TARGET_FPRS)
|| TARGET_POWERPC64
! || (mode != DFmode && mode != TFmode))
&& (TARGET_POWERPC64 || mode != DImode)
&& mode != TImode)
{
--- 2835,2841 ----
&& GET_MODE_NUNITS (mode) == 1
&& ((TARGET_HARD_FLOAT && TARGET_FPRS)
|| TARGET_POWERPC64
! || ((mode != DFmode || TARGET_E500_DOUBLE) && mode != TFmode))
&& (TARGET_POWERPC64 || mode != DImode)
&& mode != TImode)
{
*************** rs6000_legitimize_address (rtx x, rtx ol
*** 2825,2831 ****
reg = force_reg (Pmode, x);
return reg;
}
! else if (SPE_VECTOR_MODE (mode))
{
/* We accept [reg + reg] and [reg + OFFSET]. */
--- 2854,2861 ----
reg = force_reg (Pmode, x);
return reg;
}
! else if (SPE_VECTOR_MODE (mode)
! || (TARGET_E500_DOUBLE && mode == DFmode))
{
/* We accept [reg + reg] and [reg + OFFSET]. */
*************** rs6000_legitimize_address (rtx x, rtx ol
*** 2869,2875 ****
&& GET_CODE (x) != CONST_INT
&& GET_CODE (x) != CONST_DOUBLE
&& CONSTANT_P (x)
! && ((TARGET_HARD_FLOAT && TARGET_FPRS) || mode != DFmode)
&& mode != DImode
&& mode != TImode)
{
--- 2899,2906 ----
&& GET_CODE (x) != CONST_INT
&& GET_CODE (x) != CONST_DOUBLE
&& CONSTANT_P (x)
! && ((TARGET_HARD_FLOAT && TARGET_FPRS)
! || (mode != DFmode || TARGET_E500_DOUBLE))
&& mode != DImode
&& mode != TImode)
{
*************** rs6000_legitimize_reload_address (rtx x,
*** 3216,3221 ****
--- 3247,3253 ----
&& REG_MODE_OK_FOR_BASE_P (XEXP (x, 0), mode)
&& GET_CODE (XEXP (x, 1)) == CONST_INT
&& !SPE_VECTOR_MODE (mode)
+ && !(TARGET_E500_DOUBLE && mode == DFmode)
&& !ALTIVEC_VECTOR_MODE (mode))
{
HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
*************** rs6000_legitimate_address (enum machine_
*** 3312,3317 ****
--- 3344,3350 ----
if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
&& !ALTIVEC_VECTOR_MODE (mode)
&& !SPE_VECTOR_MODE (mode)
+ && !(TARGET_E500_DOUBLE && mode == DFmode)
&& TARGET_UPDATE
&& legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
return 1;
*************** rs6000_legitimate_address (enum machine_
*** 3332,3338 ****
if (mode != TImode
&& ((TARGET_HARD_FLOAT && TARGET_FPRS)
|| TARGET_POWERPC64
! || (mode != DFmode && mode != TFmode))
&& (TARGET_POWERPC64 || mode != DImode)
&& legitimate_indexed_address_p (x, reg_ok_strict))
return 1;
--- 3365,3371 ----
if (mode != TImode
&& ((TARGET_HARD_FLOAT && TARGET_FPRS)
|| TARGET_POWERPC64
! || ((mode != DFmode || TARGET_E500_DOUBLE) && mode != TFmode))
&& (TARGET_POWERPC64 || mode != DImode)
&& legitimate_indexed_address_p (x, reg_ok_strict))
return 1;
*************** rs6000_generate_compare (enum rtx_code c
*** 9868,9899 ****
&& rs6000_compare_fp_p)
{
rtx cmp, or1, or2, or_result, compare_result2;
/* Note: The E500 comparison instructions set the GT bit (x +
1), on success. This explains the mess. */
switch (code)
! {
! case EQ: case UNEQ: case NE: case LTGT:
! cmp = flag_finite_math_only
! ? gen_tstsfeq_gpr (compare_result, rs6000_compare_op0,
! rs6000_compare_op1)
! : gen_cmpsfeq_gpr (compare_result, rs6000_compare_op0,
! rs6000_compare_op1);
break;
! case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
! cmp = flag_finite_math_only
! ? gen_tstsfgt_gpr (compare_result, rs6000_compare_op0,
! rs6000_compare_op1)
! : gen_cmpsfgt_gpr (compare_result, rs6000_compare_op0,
! rs6000_compare_op1);
break;
! case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
! cmp = flag_finite_math_only
! ? gen_tstsflt_gpr (compare_result, rs6000_compare_op0,
! rs6000_compare_op1)
! : gen_cmpsflt_gpr (compare_result, rs6000_compare_op0,
! rs6000_compare_op1);
break;
default:
abort ();
--- 9901,9960 ----
&& rs6000_compare_fp_p)
{
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 +
1), on success. This explains the mess. */
switch (code)
! {
! case EQ: case UNEQ: case NE: case LTGT:
! if (op_mode == SFmode)
! cmp = flag_finite_math_only
! ? gen_tstsfeq_gpr (compare_result, rs6000_compare_op0,
! 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;
! case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
! if (op_mode == SFmode)
! cmp = flag_finite_math_only
! ? gen_tstsfgt_gpr (compare_result, rs6000_compare_op0,
! 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;
! case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
! if (op_mode == SFmode)
! cmp = flag_finite_math_only
! ? gen_tstsflt_gpr (compare_result, rs6000_compare_op0,
! 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;
default:
abort ();
*************** rs6000_generate_compare (enum rtx_code c
*** 9919,9929 ****
compare_result2 = gen_reg_rtx (CCFPmode);
/* Do the EQ. */
! cmp = flag_finite_math_only
! ? gen_tstsfeq_gpr (compare_result2, rs6000_compare_op0,
! rs6000_compare_op1)
! : gen_cmpsfeq_gpr (compare_result2, rs6000_compare_op0,
! rs6000_compare_op1);
emit_insn (cmp);
or1 = gen_rtx_GT (SImode, compare_result, const0_rtx);
--- 9980,9998 ----
compare_result2 = gen_reg_rtx (CCFPmode);
/* Do the EQ. */
! if (op_mode == SFmode)
! cmp = flag_finite_math_only
! ? gen_tstsfeq_gpr (compare_result2, rs6000_compare_op0,
! 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);
or1 = gen_rtx_GT (SImode, compare_result, const0_rtx);
*************** emit_frame_save (rtx frame_reg, rtx fram
*** 11950,11955 ****
--- 12019,12025 ----
/* Some cases that need register indexed addressing. */
if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
+ || (TARGET_E500_DOUBLE && mode == DFmode)
|| (TARGET_SPE_ABI
&& SPE_VECTOR_MODE (mode)
&& !SPE_CONST_OFFSET_OK (offset)))
*************** gen_frame_mem_offset (enum machine_mode
*** 11989,11995 ****
int_rtx = GEN_INT (offset);
! if (TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
{
offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
emit_move_insn (offset_rtx, int_rtx);
--- 12059,12066 ----
int_rtx = GEN_INT (offset);
! if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
! || (TARGET_E500_DOUBLE && mode == DFmode))
{
offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
emit_move_insn (offset_rtx, int_rtx);
*************** rs6000_dwarf_register_span (rtx reg)
*** 16341,16347 ****
{
unsigned regno;
! if (!TARGET_SPE || !SPE_VECTOR_MODE (GET_MODE (reg)))
return NULL_RTX;
regno = REGNO (reg);
--- 16412,16422 ----
{
unsigned regno;
! if (TARGET_SPE
! && (SPE_VECTOR_MODE (GET_MODE (reg))
! || (TARGET_E500_DOUBLE && GET_MODE (reg) == DFmode)))
! ;
! else
return NULL_RTX;
regno = REGNO (reg);
Index: config/rs6000/spe.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/spe.md,v
retrieving revision 1.16.10.9
diff -c -p -r1.16.10.9 spe.md
*** config/rs6000/spe.md 28 Jul 2004 12:15:06 -0000 1.16.10.9
--- config/rs6000/spe.md 22 Oct 2004 19:00:42 -0000
***************
*** 21,27 ****
(define_constants
[(SPE_ACC_REGNO 111)
! (SPEFSCR_REGNO 112)])
(define_insn "*negsf2_gpr"
[(set (match_operand:SF 0 "gpc_reg_operand" "=r")
--- 21,35 ----
(define_constants
[(SPE_ACC_REGNO 111)
! (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"
[(set (match_operand:SF 0 "gpc_reg_operand" "=r")
***************
*** 2532,2534 ****
--- 2540,2604 ----
"TARGET_HARD_FLOAT && !TARGET_FPRS && flag_unsafe_math_optimizations"
"efststlt %0,%1,%2"
[(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")])
Index: doc/invoke.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/invoke.texi,v
retrieving revision 1.390.2.33
diff -c -p -r1.390.2.33 invoke.texi
*** doc/invoke.texi 6 Oct 2004 20:15:08 -0000 1.390.2.33
--- doc/invoke.texi 22 Oct 2004 19:00:50 -0000
*************** in the following sections.
*** 439,445 ****
-mabi=spe -mabi=no-spe @gol
-misel=yes -misel=no @gol
-mspe=yes -mspe=no @gol
! -mfloat-gprs=yes -mfloat-gprs=no @gol
-mprototype -mno-prototype @gol
-msim -mmvme -mads -myellowknife -memb -msdata @gol
-msdata=@var{opt} -mvxworks -mwindiss -G @var{num} -pthread}
--- 439,445 ----
-mabi=spe -mabi=no-spe @gol
-misel=yes -misel=no @gol
-mspe=yes -mspe=no @gol
! -mfloat-gprs=yes -mfloat-gprs=no -mfloat-gprs=single -mfloat-gprs=double @gol
-mprototype -mno-prototype @gol
-msim -mmvme -mads -myellowknife -memb -msdata @gol
-msdata=@var{opt} -mvxworks -mwindiss -G @var{num} -pthread}
*************** This switch enables or disables the gene
*** 7129,7140 ****
This switch enables or disables the generation of SPE simd
instructions.
! @item -mfloat-gprs=@var{yes/no}
@itemx -mfloat-gprs
@opindex mfloat-gprs
This switch enables or disables the generation of floating point
operations on the general purpose registers for architectures that
! support it. This option is currently only available on the MPC8540.
@item -mfull-toc
@itemx -mno-fp-in-toc
--- 7129,7151 ----
This switch enables or disables the generation of SPE simd
instructions.
! @item -mfloat-gprs=@var{yes/single/double/no}
@itemx -mfloat-gprs
@opindex mfloat-gprs
This switch enables or disables the generation of floating point
operations on the general purpose registers for architectures that
! 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 -mfull-toc
@itemx -mno-fp-in-toc