patch: preliminary ppc 8548 support

Aldy Hernandez aldyh@redhat.com
Thu Oct 21 21:56:00 GMT 2004


Hi folks.  Hi Geoff.

Here is a patch that is tested and ready to go.  As you can see, it
doesn't affect the rest of the port.

Missing still are the .md changes (both expanders and individual patterns).
I wanted to get the preliminary infrastructure in first.  Oh yeah,
there are some ABI issues I need to work on.  These only affect e500 v2,
and require some patches fixing some bogosity in the rest of the compiler.
More on this later.

Is the subport acceptable?

Aldy

	* 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.

Index: config.gcc
===================================================================
RCS file: /cvs/uberbaum/gcc/config.gcc,v
retrieving revision 1.494
diff -c -p -r1.494 config.gcc
*** config.gcc	12 Oct 2004 15:38:26 -0000	1.494
--- config.gcc	21 Oct 2004 21:28:48 -0000
*************** fi
*** 2665,2670 ****
--- 2665,2675 ----
  		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	21 Oct 2004 21:28:48 -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/uberbaum/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.342
diff -c -p -r1.342 rs6000.h
*** config/rs6000/rs6000.h	15 Oct 2004 18:50:55 -0000	1.342
--- config/rs6000/rs6000.h	21 Oct 2004 21:28:49 -0000
*************** extern const char *rs6000_warn_altivec_l
*** 568,573 ****
--- 568,575 ----
  #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
Index: config/rs6000/eabi.h
===================================================================
RCS file: /cvs/uberbaum/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	21 Oct 2004 21:28:49 -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/uberbaum/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	21 Oct 2004 21:28:50 -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/uberbaum/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.722
diff -c -p -r1.722 rs6000.c
*** config/rs6000/rs6000.c	7 Oct 2004 21:16:20 -0000	1.722
--- config/rs6000/rs6000.c	21 Oct 2004 21:29:00 -0000
*************** static void rs6000_parse_abi_options (vo
*** 723,728 ****
--- 723,729 ----
  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 compute_save_world_info(rs6000_stack_t *info_ptr);
*************** rs6000_override_options (const char *def
*** 1118,1123 ****
--- 1119,1126 ----
  	 {"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
*** 1291,1304 ****
    /* 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 ();
--- 1294,1307 ----
    /* 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
*** 1309,1314 ****
--- 1312,1320 ----
  #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
    SUBSUBTARGET_OVERRIDE_OPTIONS;
  #endif
+ #ifdef SUB3TARGET_OVERRIDE_OPTIONS
+   SUB3TARGET_OVERRIDE_OPTIONS;
+ #endif
  
    if (TARGET_E500)
      {
*************** rs6000_parse_abi_options (void)
*** 1621,1626 ****
--- 1627,1649 ----
      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
*** 2161,2167 ****
      return 0;
  
    /* Consider all constants with -msoft-float to be easy.  */
!   if ((TARGET_SOFT_FLOAT || !TARGET_FPRS)
        && mode != DImode)
      return 1;
  
--- 2184,2190 ----
      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
*** 2195,2200 ****
--- 2218,2226 ----
        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);
  
*************** rs6000_legitimate_offset_address_p (enum
*** 3171,3176 ****
--- 3197,3205 ----
        return SPE_CONST_OFFSET_OK (offset);
  
      case DFmode:
+       if (TARGET_E500_DOUBLE)
+ 	return SPE_CONST_OFFSET_OK (offset);
+ 
      case DImode:
        if (mode == DFmode || !TARGET_POWERPC64)
  	extra = 4;
*************** rs6000_legitimize_address (rtx x, rtx ol
*** 3323,3329 ****
  	   && GET_MODE_NUNITS (mode) == 1
  	   && ((TARGET_HARD_FLOAT && TARGET_FPRS)
  	       || TARGET_POWERPC64
! 	       || (mode != DFmode && mode != TFmode))
  	   && (TARGET_POWERPC64 || mode != DImode)
  	   && mode != TImode)
      {
--- 3352,3358 ----
  	   && 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
*** 3342,3348 ****
        reg = force_reg (Pmode, x);
        return reg;
      }
!   else if (SPE_VECTOR_MODE (mode))
      {
        /* We accept [reg + reg] and [reg + OFFSET].  */
  
--- 3371,3378 ----
        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
*** 3386,3392 ****
  	   && GET_CODE (x) != CONST_INT
  	   && GET_CODE (x) != CONST_DOUBLE
  	   && CONSTANT_P (x)
! 	   && ((TARGET_HARD_FLOAT && TARGET_FPRS) || mode != DFmode)
  	   && mode != DImode
  	   && mode != TImode)
      {
--- 3416,3423 ----
  	   && 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,
*** 3733,3738 ****
--- 3764,3770 ----
        && 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_
*** 3836,3841 ****
--- 3868,3874 ----
    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_
*** 3857,3863 ****
        && mode != TFmode
        && ((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;
--- 3890,3896 ----
        && mode != TFmode
        && ((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_hard_regno_nregs (int regno, enum
*** 3922,3927 ****
--- 3955,3963 ----
    if (FP_REGNO_P (regno))
      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))
      return (GET_MODE_SIZE (mode) + UNITS_PER_SPE_WORD - 1) / UNITS_PER_SPE_WORD;
  
*************** rs6000_generate_compare (enum rtx_code c
*** 10857,10862 ****
--- 10893,10902 ----
        && 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.  */
*************** rs6000_generate_compare (enum rtx_code c
*** 10864,10891 ****
        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 ();
  	}
  
        /* Synthesize LE and GE from LT/GT || EQ.  */
--- 10904,10955 ----
        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 ();
  	}
  
        /* Synthesize LE and GE from LT/GT || EQ.  */
*************** rs6000_generate_compare (enum rtx_code c
*** 10908,10918 ****
  	  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);
--- 10972,10990 ----
  	  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
*** 13282,13287 ****
--- 13354,13360 ----
  
    /* 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 
*** 13321,13327 ****
  
    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);
--- 13394,13401 ----
  
    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)
*** 18052,18058 ****
  {
    unsigned regno;
  
!   if (!TARGET_SPE || !SPE_VECTOR_MODE (GET_MODE (reg)))
      return NULL_RTX;
  
    regno = REGNO (reg);
--- 18126,18136 ----
  {
    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/uberbaum/gcc/config/rs6000/spe.md,v
retrieving revision 1.26
diff -c -p -r1.26 spe.md
*** config/rs6000/spe.md	28 Jul 2004 12:13:13 -0000	1.26
--- config/rs6000/spe.md	21 Oct 2004 21:29:00 -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/uberbaum/gcc/doc/invoke.texi,v
retrieving revision 1.544
diff -c -p -r1.544 invoke.texi
*** doc/invoke.texi	12 Oct 2004 15:38:30 -0000	1.544
--- doc/invoke.texi	21 Oct 2004 21:29:09 -0000
*************** See RS/6000 and PowerPC Options.
*** 615,621 ****
  -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}
--- 615,621 ----
  -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
*** 10272,10283 ****
  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 -m32
  @itemx -m64
--- 10272,10294 ----
  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 -m32
  @itemx -m64



More information about the Gcc-patches mailing list