From ec555f3273efb2947e0a1ed6bbe23d048a4c50a9 Mon Sep 17 00:00:00 2001 From: "J\"orn Rennecke" Date: Thu, 12 Dec 2002 17:11:13 +0000 Subject: [PATCH] sh.c (reg_class_from_letter): No longer const. * 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. From-SVN: r60076 --- gcc/ChangeLog | 17 +++++++++++++++++ gcc/config/sh/sh.c | 35 +++++++++++++++++++++++------------ gcc/config/sh/sh.h | 39 +++++++++++++++++++++------------------ gcc/config/sh/sh.md | 15 ++++++++++----- 4 files changed, 71 insertions(+), 35 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 724738e1f77b..79def92e5885 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,20 @@ +Thu Dec 12 16:24:59 2002 J"orn Rennecke + + * 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 * 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 e77bc11bd171..824914c42d22 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 0d0869099af9..f84e6fb8956f 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 e545b0a63d2d..1df69d194958 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")) -- 2.43.5