patch to fix simd[24].c compilation for little endian sh-compact checked in

Joern Rennecke joern.rennecke@superh.com
Thu Dec 12 09:13:00 GMT 2002


-- 
--------------------------
SuperH (UK) Ltd.
2410 Aztec West / Almondsbury / BRISTOL / BS32 4QX
T:+44 1454 465658
-------------- next part --------------
Thu Dec 12 16:24:59 2002  J"orn Rennecke <joern.rennecke@superh.com>

	* sh.c (reg_class_from_letter): No longer const.  Add 'e' entry.
	(sh_register_move_cost): Add clause for SImode fp-fp moves.
	Increase cost for moves involving multiple general purpose registers.
	* sh.h (OVERRIDE_OPTIONS): Set reg_class_from_letter['e'] according to
	TARGET_FMOVD.
	(HARD_REGNO_MODE_OK): Allow V2SFmode and V4SFmode in general purpose
	registers, and SImode in fp registers, for ! TARGET_SHMEDIA.
	(enum reg_class reg_class_from_letter): No longer const.
	(SECONDARY_OUTPUT_RELOAD_CLASS): Use REGCLASS_HAS_FP_REG /
	REGCLASS_HAS_GENERAL_REG.
	Handle SImode moves from/to fp registers.
	! TARGET_SHMEDIA && TARGET_FMOVD.
	(SECONDARY_INPUT_RELOAD_CLASS): Use REGCLASS_HAS_FP_REG.
	* sh.md (movsi_ie): Add alternatives to move from / to fp regisyters.

Index: config/sh/sh.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sh/sh.c,v
retrieving revision 1.186
diff -p -r1.186 sh.c
*** config/sh/sh.c	12 Dec 2002 16:40:49 -0000	1.186
--- config/sh/sh.c	12 Dec 2002 17:08:49 -0000
*************** char sh_additional_register_names[ADDREG
*** 154,169 ****
    = SH_ADDITIONAL_REGISTER_NAMES_INITIALIZER;
  
  /* Provide reg_class from a letter such as appears in the machine
!    description.  */
  
! const enum reg_class reg_class_from_letter[] =
  {
!   /* a */ ALL_REGS, /* b */ TARGET_REGS, /* c */ FPSCR_REGS, /* d */ DF_REGS,
!   /* e */ NO_REGS, /* f */ FP_REGS, /* g */ NO_REGS, /* h */ NO_REGS,
!   /* i */ NO_REGS, /* j */ NO_REGS, /* k */ SIBCALL_REGS, /* l */ PR_REGS,
!   /* m */ NO_REGS, /* n */ NO_REGS, /* o */ NO_REGS, /* p */ NO_REGS,
!   /* q */ NO_REGS, /* r */ NO_REGS, /* s */ NO_REGS, /* t */ T_REGS,
!   /* u */ NO_REGS, /* v */ NO_REGS, /* w */ FP0_REGS, /* x */ MAC_REGS,
    /* y */ FPUL_REGS, /* z */ R0_REGS
  };
  
--- 154,170 ----
    = SH_ADDITIONAL_REGISTER_NAMES_INITIALIZER;
  
  /* Provide reg_class from a letter such as appears in the machine
!    description.  *: target independently reserved letter.
!    reg_class_from_letter['e'] is set to NO_REGS for TARGET_FMOVD.  */
  
! enum reg_class reg_class_from_letter[] =
  {
!   /* a */ ALL_REGS,  /* b */ TARGET_REGS, /* c */ FPSCR_REGS, /* d */ DF_REGS,
!   /* e */ FP_REGS,   /* f */ FP_REGS,  /* g **/ NO_REGS,     /* h */ NO_REGS,
!   /* i **/ NO_REGS,  /* j */ NO_REGS,  /* k */ SIBCALL_REGS, /* l */ PR_REGS,
!   /* m **/ NO_REGS,  /* n **/ NO_REGS, /* o **/ NO_REGS,     /* p **/ NO_REGS,
!   /* q */ NO_REGS,   /* r **/ NO_REGS, /* s **/ NO_REGS,     /* t */ T_REGS,
!   /* u */ NO_REGS,   /* v */ NO_REGS,  /* w */ FP0_REGS,     /* x */ MAC_REGS,
    /* y */ FPUL_REGS, /* z */ R0_REGS
  };
  
*************** sh_mark_label (address, nuses)
*** 7784,7792 ****
  /* Compute extra cost of moving data between one register class
     and another.  */
  
! /* Regclass always uses 2 for moves in the same register class;
!    If SECONDARY*_RELOAD_CLASS says something about the src/dst pair,
!    it uses this information.  Hence, the general register <-> floating point
     register information here is not used for SFmode.  */
  
  int
--- 7785,7792 ----
  /* Compute extra cost of moving data between one register class
     and another.  */
  
! /* If SECONDARY*_RELOAD_CLASS says something about the src/dst pair, regclass
!    uses this information.  Hence, the general register <-> floating point
     register information here is not used for SFmode.  */
  
  int
*************** sh_register_move_cost (mode, srcclass, d
*** 7797,7802 ****
--- 7797,7807 ----
    if (dstclass == T_REGS || dstclass == PR_REGS)
      return 10;
  
+   if (mode == SImode && ! TARGET_SHMEDIA && TARGET_FMOVD
+       && REGCLASS_HAS_FP_REG (srcclass)
+       && REGCLASS_HAS_FP_REG (dstclass))
+     return 4;
+ 
    if ((REGCLASS_HAS_FP_REG (dstclass)
         && REGCLASS_HAS_GENERAL_REG (srcclass))
        || (REGCLASS_HAS_GENERAL_REG (dstclass)
*************** sh_register_move_cost (mode, srcclass, d
*** 7824,7830 ****
        || (dstclass == FPSCR_REGS && ! REGCLASS_HAS_GENERAL_REG (srcclass)))
    return 4;
  
!   return 2 * ((GET_MODE_SIZE (mode) + 7) / 8U);
  }
  
  #include "gt-sh.h"
--- 7829,7841 ----
        || (dstclass == FPSCR_REGS && ! REGCLASS_HAS_GENERAL_REG (srcclass)))
    return 4;
  
!   if (TARGET_SHMEDIA
!       || (TARGET_FMOVD
! 	  && ! REGCLASS_HAS_GENERAL_REG (srcclass)
! 	  && ! REGCLASS_HAS_GENERAL_REG (dstclass)))
!     return 2 * ((GET_MODE_SIZE (mode) + 7) / 8U);
! 
!   return 2 * ((GET_MODE_SIZE (mode) + 3) / 4U);
  }
  
  #include "gt-sh.h"
Index: config/sh/sh.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sh/sh.h,v
retrieving revision 1.177
diff -p -r1.177 sh.h
*** config/sh/sh.h	11 Dec 2002 20:16:27 -0000	1.177
--- config/sh/sh.h	12 Dec 2002 17:08:49 -0000
*************** do {									\
*** 444,449 ****
--- 444,451 ----
         targetm.asm_out.aligned_op.di = NULL;				\
         targetm.asm_out.unaligned_op.di = NULL;				\
      }									\
+   if (TARGET_FMOVD)							\
+     reg_class_from_letter['e'] = NO_REGS;				\
  									\
    for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)		\
      if (! VALID_REGISTER_P (regno))					\
*************** extern char sh_additional_register_names
*** 912,927 ****
     ? 1 \
     : (MODE) == V2SFmode \
     ? ((FP_REGISTER_P (REGNO) && ((REGNO) - FIRST_FP_REG) % 2 == 0) \
!       || (TARGET_SHMEDIA && GENERAL_REGISTER_P (REGNO))) \
     : (MODE) == V4SFmode \
!    ? (FP_REGISTER_P (REGNO) && ((REGNO) - FIRST_FP_REG) % 4 == 0) \
     : (MODE) == V16SFmode \
     ? (TARGET_SHMEDIA \
        ? (FP_REGISTER_P (REGNO) && ((REGNO) - FIRST_FP_REG) % 16 == 0) \
        : (REGNO) == FIRST_XD_REG) \
     : FP_REGISTER_P (REGNO) \
!    ? ((MODE) == SFmode \
!       || (TARGET_SHMEDIA && (MODE) == SImode) \
        || ((TARGET_SH3E || TARGET_SHMEDIA) && (MODE) == SCmode) \
        || (((TARGET_SH4 && (MODE) == DFmode) || (MODE) == DCmode \
  	   || (TARGET_SHMEDIA && ((MODE) == DFmode || (MODE) == DImode \
--- 914,929 ----
     ? 1 \
     : (MODE) == V2SFmode \
     ? ((FP_REGISTER_P (REGNO) && ((REGNO) - FIRST_FP_REG) % 2 == 0) \
!       || GENERAL_REGISTER_P (REGNO)) \
     : (MODE) == V4SFmode \
!    ? ((FP_REGISTER_P (REGNO) && ((REGNO) - FIRST_FP_REG) % 4 == 0) \
!       || (! TARGET_SHMEDIA && GENERAL_REGISTER_P (REGNO))) \
     : (MODE) == V16SFmode \
     ? (TARGET_SHMEDIA \
        ? (FP_REGISTER_P (REGNO) && ((REGNO) - FIRST_FP_REG) % 16 == 0) \
        : (REGNO) == FIRST_XD_REG) \
     : FP_REGISTER_P (REGNO) \
!    ? ((MODE) == SFmode || (MODE) == SImode \
        || ((TARGET_SH3E || TARGET_SHMEDIA) && (MODE) == SCmode) \
        || (((TARGET_SH4 && (MODE) == DFmode) || (MODE) == DCmode \
  	   || (TARGET_SHMEDIA && ((MODE) == DFmode || (MODE) == DImode \
*************** extern int regno_reg_class[FIRST_PSEUDO_
*** 1237,1243 ****
  
  /* Get reg_class from a letter such as appears in the machine
     description.  */
! extern const enum reg_class reg_class_from_letter[];
  
  #define REG_CLASS_FROM_LETTER(C) \
     ( ISLOWER (C) ? reg_class_from_letter[(C)-'a'] : NO_REGS )
--- 1239,1245 ----
  
  /* Get reg_class from a letter such as appears in the machine
     description.  */
! extern enum reg_class reg_class_from_letter[];
  
  #define REG_CLASS_FROM_LETTER(C) \
     ( ISLOWER (C) ? reg_class_from_letter[(C)-'a'] : NO_REGS )
*************** extern const enum reg_class reg_class_fr
*** 1302,1317 ****
     : (CLASS)) \
  
  #define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS,MODE,X) \
!   ((((((CLASS) == FP_REGS || (CLASS) == FP0_REGS			\
! 	|| (CLASS) == DF_REGS || (CLASS) == DF_HI_REGS)			\
!       && (GET_CODE (X) == REG && GENERAL_OR_AP_REGISTER_P (REGNO (X))))	\
!      || (((CLASS) == GENERAL_REGS || (CLASS) == R0_REGS)		\
  	 && GET_CODE (X) == REG						\
  	 && FP_REGISTER_P (REGNO (X))))					\
      && ! TARGET_SHMEDIA							\
!     && MODE == SFmode)							\
     ? FPUL_REGS								\
!    : ((CLASS) == FPUL_REGS						\
        && (GET_CODE (X) == MEM						\
  	  || (GET_CODE (X) == REG					\
  	      && (REGNO (X) >= FIRST_PSEUDO_REGISTER			\
--- 1304,1323 ----
     : (CLASS)) \
  
  #define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS,MODE,X) \
!   ((((REGCLASS_HAS_FP_REG (CLASS) 					\
!       && (GET_CODE (X) == REG						\
!       && (GENERAL_OR_AP_REGISTER_P (REGNO (X))				\
! 	  || (FP_REGISTER_P (REGNO (X)) && (MODE) == SImode		\
! 	      && TARGET_FMOVD))))					\
!      || (REGCLASS_HAS_GENERAL_REG (CLASS) 				\
  	 && GET_CODE (X) == REG						\
  	 && FP_REGISTER_P (REGNO (X))))					\
      && ! TARGET_SHMEDIA							\
!     && ((MODE) == SFmode || (MODE) == SImode))				\
     ? FPUL_REGS								\
!    : (((CLASS) == FPUL_REGS						\
!        || (REGCLASS_HAS_FP_REG (CLASS)					\
! 	   && ! TARGET_SHMEDIA && MODE == SImode))			\
        && (GET_CODE (X) == MEM						\
  	  || (GET_CODE (X) == REG					\
  	      && (REGNO (X) >= FIRST_PSEUDO_REGISTER			\
*************** extern const enum reg_class reg_class_fr
*** 1332,1339 ****
     ? GENERAL_REGS : NO_REGS)
  
  #define SECONDARY_INPUT_RELOAD_CLASS(CLASS,MODE,X)  \
!   ((((CLASS) == FP_REGS || (CLASS) == FP0_REGS || (CLASS) == DF_REGS	\
!      || (CLASS) == DF_HI_REGS)						\
      && ! TARGET_SHMEDIA							\
      && immediate_operand ((X), (MODE))					\
      && ! ((fp_zero_operand (X) || fp_one_operand (X))			\
--- 1338,1344 ----
     ? GENERAL_REGS : NO_REGS)
  
  #define SECONDARY_INPUT_RELOAD_CLASS(CLASS,MODE,X)  \
!   ((REGCLASS_HAS_FP_REG (CLASS) 					\
      && ! TARGET_SHMEDIA							\
      && immediate_operand ((X), (MODE))					\
      && ! ((fp_zero_operand (X) || fp_one_operand (X))			\
*************** extern const enum reg_class reg_class_fr
*** 1352,1358 ****
        && ((GET_CODE (X) == REG && REGNO (X) >= FIRST_PSEUDO_REGISTER)	\
  	  || (GET_CODE (X) == MEM && GET_CODE (XEXP ((X), 0)) == PLUS)))\
     ? GENERAL_REGS							\
!    : (((CLASS) == FP_REGS || (CLASS) == DF_REGS || (CLASS) == DF_HI_REGS)\
        && TARGET_SHMEDIA							\
        && immediate_operand ((X), (MODE))				\
        && (X) != CONST0_RTX (GET_MODE (X))				\
--- 1357,1363 ----
        && ((GET_CODE (X) == REG && REGNO (X) >= FIRST_PSEUDO_REGISTER)	\
  	  || (GET_CODE (X) == MEM && GET_CODE (XEXP ((X), 0)) == PLUS)))\
     ? GENERAL_REGS							\
!    : (REGCLASS_HAS_FP_REG (CLASS) 					\
        && TARGET_SHMEDIA							\
        && immediate_operand ((X), (MODE))				\
        && (X) != CONST0_RTX (GET_MODE (X))				\
*************** while (0)
*** 2807,2821 ****
  /* Compute extra cost of moving data between one register class
     and another.  */
  
! /* Regclass always uses 2 for moves in the same register class;
!    If SECONDARY*_RELOAD_CLASS says something about the src/dst pair,
!    it uses this information.  Hence, the general register <-> floating point
     register information here is not used for SFmode.  */
  
  #define REGCLASS_HAS_GENERAL_REG(CLASS) \
    ((CLASS) == GENERAL_REGS || (CLASS) == R0_REGS \
      || (! TARGET_SHMEDIA && (CLASS) == SIBCALL_REGS))
- /* NB SIBCALL_REGS are not strictly general, as they include TR0-TR4 */
  
  #define REGCLASS_HAS_FP_REG(CLASS) \
    ((CLASS) == FP0_REGS || (CLASS) == FP_REGS \
--- 2812,2824 ----
  /* Compute extra cost of moving data between one register class
     and another.  */
  
! /* If SECONDARY*_RELOAD_CLASS says something about the src/dst pair, regclass
!    uses this information.  Hence, the general register <-> floating point
     register information here is not used for SFmode.  */
  
  #define REGCLASS_HAS_GENERAL_REG(CLASS) \
    ((CLASS) == GENERAL_REGS || (CLASS) == R0_REGS \
      || (! TARGET_SHMEDIA && (CLASS) == SIBCALL_REGS))
  
  #define REGCLASS_HAS_FP_REG(CLASS) \
    ((CLASS) == FP0_REGS || (CLASS) == FP_REGS \
Index: config/sh/sh.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sh/sh.md,v
retrieving revision 1.131
diff -p -r1.131 sh.md
*** config/sh/sh.md	6 Dec 2002 20:10:50 -0000	1.131
--- config/sh/sh.md	12 Dec 2002 17:08:50 -0000
***************
*** 3408,3416 ****
  ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
  ;; ??? This allows moves from macl to fpul to be recognized, but these moves
  ;; will require a reload.
  (define_insn "movsi_ie"
!   [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,y")
! 	(match_operand:SI 1 "general_movsrc_operand" "Q,rI,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y"))]
    "TARGET_SH3E
     && (register_operand (operands[0], SImode)
         || register_operand (operands[1], SImode))"
--- 3408,3418 ----
  ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
  ;; ??? This allows moves from macl to fpul to be recognized, but these moves
  ;; will require a reload.
+ ;; ??? We can't include f/f because we need the proper FPSCR setting when
+ ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
  (define_insn "movsi_ie"
!   [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
! 	(match_operand:SI 1 "general_movsrc_operand" "Q,rI,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
    "TARGET_SH3E
     && (register_operand (operands[0], SImode)
         || register_operand (operands[1], SImode))"
***************
*** 3434,3443 ****
  	fake	%1,%0
  	lds	%1,%0
  	sts	%1,%0
  	! move optimized away"
!   [(set_attr "type" "pcload_si,move,*,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,load,store,pcload_si,gp_fpul,fpul_gp,nil")
!    (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*")
!    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
  
  (define_insn "movsi_i_lowpart"
    [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
--- 3436,3448 ----
  	fake	%1,%0
  	lds	%1,%0
  	sts	%1,%0
+ 	fsts	fpul,%0
+ 	flds	%1,fpul
+ 	fmov	%1,%0
  	! move optimized away"
!   [(set_attr "type" "pcload_si,move,*,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,load,store,pcload_si,gp_fpul,fpul_gp,fmove,fmove,fmove,nil")
!    (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
!    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
  
  (define_insn "movsi_i_lowpart"
    [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))


More information about the Gcc-patches mailing list