aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoramylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4>2002-12-12 17:11:13 +0000
committeramylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4>2002-12-12 17:11:13 +0000
commit0b3e4dc546fb89e639c2a2c0ccd855d13e06dffe (patch)
treedbf9c797639fc0b20546440999f16b2bed59edc2
parent9882801976b3e81feeb371481aa995588a5ce5b5 (diff)
* 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. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@60076 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog17
-rw-r--r--gcc/config/sh/sh.c35
-rw-r--r--gcc/config/sh/sh.h39
-rw-r--r--gcc/config/sh/sh.md15
4 files changed, 71 insertions, 35 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 724738e1f77..79def92e588 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,20 @@
+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.
+
2002-12-12 Andreas Schwab <schwab@suse.de>
* config/ia64/ia64.c (ia64_hpux_asm_file_end): Fix typo in last
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index e77bc11bd17..824914c42d2 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -154,16 +154,17 @@ char sh_additional_register_names[ADDREGNAMES_SIZE] \
= SH_ADDITIONAL_REGISTER_NAMES_INITIALIZER;
/* Provide reg_class from a letter such as appears in the machine
- description. */
+ description. *: target independently reserved letter.
+ reg_class_from_letter['e'] is set to NO_REGS for TARGET_FMOVD. */
-const enum reg_class reg_class_from_letter[] =
+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,
+ /* 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
};
@@ -7784,9 +7785,8 @@ sh_mark_label (address, nuses)
/* 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
+/* 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
@@ -7797,6 +7797,11 @@ sh_register_move_cost (mode, srcclass, dstclass)
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)
@@ -7824,7 +7829,13 @@ sh_register_move_cost (mode, srcclass, dstclass)
|| (dstclass == FPSCR_REGS && ! REGCLASS_HAS_GENERAL_REG (srcclass)))
return 4;
- return 2 * ((GET_MODE_SIZE (mode) + 7) / 8U);
+ 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"
diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h
index 0d0869099af..f84e6fb8956 100644
--- a/gcc/config/sh/sh.h
+++ b/gcc/config/sh/sh.h
@@ -444,6 +444,8 @@ do { \
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)) \
@@ -912,16 +914,16 @@ extern char sh_additional_register_names[ADDREGNAMES_SIZE] \
? 1 \
: (MODE) == V2SFmode \
? ((FP_REGISTER_P (REGNO) && ((REGNO) - FIRST_FP_REG) % 2 == 0) \
- || (TARGET_SHMEDIA && GENERAL_REGISTER_P (REGNO))) \
+ || GENERAL_REGISTER_P (REGNO)) \
: (MODE) == V4SFmode \
- ? (FP_REGISTER_P (REGNO) && ((REGNO) - FIRST_FP_REG) % 4 == 0) \
+ ? ((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 \
- || (TARGET_SHMEDIA && (MODE) == SImode) \
+ ? ((MODE) == SFmode || (MODE) == SImode \
|| ((TARGET_SH3E || TARGET_SHMEDIA) && (MODE) == SCmode) \
|| (((TARGET_SH4 && (MODE) == DFmode) || (MODE) == DCmode \
|| (TARGET_SHMEDIA && ((MODE) == DFmode || (MODE) == DImode \
@@ -1237,7 +1239,7 @@ extern int regno_reg_class[FIRST_PSEUDO_REGISTER];
/* Get reg_class from a letter such as appears in the machine
description. */
-extern const enum reg_class reg_class_from_letter[];
+extern enum reg_class reg_class_from_letter[];
#define REG_CLASS_FROM_LETTER(C) \
( ISLOWER (C) ? reg_class_from_letter[(C)-'a'] : NO_REGS )
@@ -1302,16 +1304,20 @@ extern const enum reg_class reg_class_from_letter[];
: (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) \
+ ((((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) == SFmode || (MODE) == SImode)) \
? FPUL_REGS \
- : ((CLASS) == 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 \
@@ -1332,8 +1338,7 @@ extern const enum reg_class reg_class_from_letter[];
? 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) \
+ ((REGCLASS_HAS_FP_REG (CLASS) \
&& ! TARGET_SHMEDIA \
&& immediate_operand ((X), (MODE)) \
&& ! ((fp_zero_operand (X) || fp_one_operand (X)) \
@@ -1352,7 +1357,7 @@ extern const enum reg_class reg_class_from_letter[];
&& ((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)\
+ : (REGCLASS_HAS_FP_REG (CLASS) \
&& TARGET_SHMEDIA \
&& immediate_operand ((X), (MODE)) \
&& (X) != CONST0_RTX (GET_MODE (X)) \
@@ -2807,15 +2812,13 @@ while (0)
/* 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
+/* 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))
-/* NB SIBCALL_REGS are not strictly general, as they include TR0-TR4 */
#define REGCLASS_HAS_FP_REG(CLASS) \
((CLASS) == FP0_REGS || (CLASS) == FP_REGS \
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index e545b0a63d2..1df69d19495 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -3408,9 +3408,11 @@
;; (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,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"))]
+ [(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,10 +3436,13 @@
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,nil")
- (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*")
- (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
+ [(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"))