aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/sh
diff options
context:
space:
mode:
authorJ"orn Rennecke <joern.rennecke@st.com>2005-11-24 18:55:53 +0000
committerJoern Rennecke <amylaar@gcc.gnu.org>2005-11-24 18:55:53 +0000
commit8a99f6f92fd255690cdc0a1712c7c2f7e1bdcfe8 (patch)
treec4e97f2cd689b954ad779a8f0f2c7757912a91f8 /gcc/config/sh
parent1a598a979ba864052b8a922d957c038493411e47 (diff)
downloadgcc-8a99f6f92fd255690cdc0a1712c7c2f7e1bdcfe8.zip
gcc-8a99f6f92fd255690cdc0a1712c7c2f7e1bdcfe8.tar.gz
gcc-8a99f6f92fd255690cdc0a1712c7c2f7e1bdcfe8.tar.bz2
re PR target/21623 (ICE in reload_cse_simplify_operands, at postreload.c:391)
PR target/21623: * regclass.c (FORBIDDEN_INC_DEC_CLASSES): Remove SECONDARY_INPUT_RELOAD_CLASS and SECONDARY_OUTPUT_RELOAD_CLASS tests. (init_fake_stack_mems): Remove HAVE_SECONDARY_RELOADS test. (memory_move_secondary_cost, init_reg_autoinc): Remove SECONDARY_INPUT_RELOAD_CLASS / SECONDARY_OUTPUT_RELOAD_CLASS tests. Replace SECONDARY_{IN,OUT}PUT_RELOAD_CLASS use with secondary_reload_class call. (copy_cost): Likewise. Add new parameter prev_sri. Changed all callers. * reload.c (entire file): Remove HAVE_SECONDARY_RELOADS checks. (push_secondary_reload): Use secondary_reload target hook. (secondary_reload_class, scratch_reload_class): New functions. (push_reload): Remove SECONDARY_INPUT_RELOAD_CLASS and SECONDARY_OUTPUT_RELOAD_CLASS tests. Replace SECONDARY_{IN,OUT}PUT_RELOAD_CLASS use with secondary_reload_class call. * reload.h (HAVE_SECONDARY_RELOADS): Don't define nor test. (secondary_reload_class, scratch_reload_class): Declare. * reload1.c: Include target.h. (reload_adjust_reg_for_temp): New function. (reload_adjust_reg_for_icode): Likewise. (choose_reload_regs): Remove SECONDARY_INPUT_RELOAD_CLASS test. Replace SECONDARY_INPUT_RELOAD_CLASS use with secondary_reload_class call. (emit_input_reload_insns): Likewise. Rewrite secondary reload checks for inheritance. Support case when both secondary & tertiary reloads are for intermediate registers. (emit_output_reload_insns): Replace SECONDARY_OUTPUT_RELOAD_CLASS use with secondary_reload_class call. Support case when both secondary & tertiary reloads are for intermediate registers. * target-def.h (TARGET_SECONDARY_RELOAD): Provide default definition. (TARGET_INITIALIZER) Add TARGET_SECONDARY_RELOAD. * target.h (secondary_reload_info): New struct / typedef. (struct gcc_target): New member secondary_reload. * targhooks.c Include reload.h, optabs.h and recog.h. (default_secondary_reload): New function. * targhooks.h (default_secondary_reload): Declare. * doc/tm.texi: Document secondary_reload target hook. Update description of SECONDARY_*RELOAD_CLASS and reload_{in,out}<mode>. * doc/md.texi: Likewise. * sh-protos.h (sh_secondary_reload): Declare. * sh.c (TARGET_SECONDARY_RELOAD): Override. (sh_secondary_reload): New function. * sh.h (SECONDARY_INOUT_RELOAD_CLASS): Don't define. (SECONDARY_OUTPUT_RELOAD_CLASS): Likewise. (SECONDARY_INPUT_RELOAD_CLASS): Likewise. (HAVE_SECONDARY_RELOADS): Define. * sh.md (reload_indf): Rename to: (reload_indf__frn). (reload_outdf): Rename to: (reload_outdf__RnFRm). (reload_insf): Rename to: (reload_insf__frn). (reload_insi): Rename to: (reload_insi__i_fpul). From-SVN: r107468
Diffstat (limited to 'gcc/config/sh')
-rw-r--r--gcc/config/sh/sh-protos.h4
-rw-r--r--gcc/config/sh/sh.c103
-rw-r--r--gcc/config/sh/sh.h4
-rw-r--r--gcc/config/sh/sh.md10
4 files changed, 116 insertions, 5 deletions
diff --git a/gcc/config/sh/sh-protos.h b/gcc/config/sh/sh-protos.h
index 564c1be..a066154 100644
--- a/gcc/config/sh/sh-protos.h
+++ b/gcc/config/sh/sh-protos.h
@@ -165,6 +165,10 @@ extern int shmedia_cleanup_truncate (rtx *, void *);
extern int sh_contains_memref_p (rtx);
extern rtx shmedia_prepare_call_address (rtx fnaddr, int is_sibcall);
+struct secondary_reload_info;
+extern enum reg_class sh_secondary_reload (bool, rtx, enum reg_class,
+ enum machine_mode,
+ struct secondary_reload_info *);
#endif /* ! GCC_SH_PROTOS_H */
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index e11d557..1bcf81d 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -500,6 +500,9 @@ static int hard_regs_intersect_p (HARD_REG_SET *, HARD_REG_SET *);
#define TARGET_ADJUST_UNROLL_MAX sh_adjust_unroll_max
#endif
+#undef TARGET_SECONDARY_RELOAD
+#define TARGET_SECONDARY_RELOAD sh_secondary_reload
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Implement TARGET_HANDLE_OPTION. */
@@ -10672,6 +10675,106 @@ shmedia_prepare_call_address (rtx fnaddr, int is_sibcall)
return fnaddr;
}
+enum reg_class
+sh_secondary_reload (bool in_p, rtx x, enum reg_class class,
+ enum machine_mode mode, secondary_reload_info *sri)
+{
+ if (in_p)
+ {
+ if (REGCLASS_HAS_FP_REG (class)
+ && ! TARGET_SHMEDIA
+ && immediate_operand ((x), mode)
+ && ! ((fp_zero_operand (x) || fp_one_operand (x))
+ && mode == SFmode && fldi_ok ()))
+ switch (mode)
+ {
+ case SFmode:
+ sri->icode = CODE_FOR_reload_insf__frn;
+ return NO_REGS;
+ case DFmode:
+ sri->icode = CODE_FOR_reload_indf__frn;
+ return NO_REGS;
+ case SImode:
+ /* ??? If we knew that we are in the appropriate mode -
+ single precision - we could use a reload pattern directly. */
+ return FPUL_REGS;
+ default:
+ abort ();
+ }
+ if (class == FPUL_REGS
+ && ((GET_CODE (x) == REG
+ && (REGNO (x) == MACL_REG || REGNO (x) == MACH_REG
+ || REGNO (x) == T_REG))
+ || GET_CODE (x) == PLUS))
+ return GENERAL_REGS;
+ if (class == FPUL_REGS && immediate_operand (x, mode))
+ {
+ if (GET_CODE (x) == CONST_INT && CONST_OK_FOR_I08 (INTVAL (x)))
+ return GENERAL_REGS;
+ sri->icode = CODE_FOR_reload_insi__i_fpul;
+ return NO_REGS;
+ }
+ if (class == FPSCR_REGS
+ && ((GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER)
+ || (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == PLUS)))
+ return GENERAL_REGS;
+ if (REGCLASS_HAS_FP_REG (class)
+ && TARGET_SHMEDIA
+ && immediate_operand (x, mode)
+ && x != CONST0_RTX (GET_MODE (x))
+ && GET_MODE (x) != V4SFmode)
+ return GENERAL_REGS;
+ if ((mode == QImode || mode == HImode)
+ && TARGET_SHMEDIA && inqhi_operand (x, mode))
+ {
+ sri->icode = ((mode == QImode)
+ ? CODE_FOR_reload_inqi : CODE_FOR_reload_inhi);
+ return NO_REGS;
+ }
+ if (TARGET_SHMEDIA && class == GENERAL_REGS
+ && (GET_CODE (x) == LABEL_REF || PIC_DIRECT_ADDR_P (x)))
+ return TARGET_REGS;
+ } /* end of input-only processing. */
+
+ if (((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))
+ return FPUL_REGS;
+ if ((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
+ || REGNO (x) == T_REG
+ || system_reg_operand (x, VOIDmode)))))
+ {
+ if (class == FPUL_REGS)
+ return GENERAL_REGS;
+ return FPUL_REGS;
+ }
+ if ((class == TARGET_REGS
+ || (TARGET_SHMEDIA && class == SIBCALL_REGS))
+ && !EXTRA_CONSTRAINT_Csy (x)
+ && (GET_CODE (x) != REG || ! GENERAL_REGISTER_P (REGNO (x))))
+ return GENERAL_REGS;
+ if ((class == MAC_REGS || class == PR_REGS)
+ && GET_CODE (x) == REG && ! GENERAL_REGISTER_P (REGNO (x))
+ && class != REGNO_REG_CLASS (REGNO (x)))
+ return GENERAL_REGS;
+ if (class != GENERAL_REGS && GET_CODE (x) == REG
+ && TARGET_REGISTER_P (REGNO (x)))
+ return GENERAL_REGS;
+ return NO_REGS;
+}
+
enum sh_divide_strategy_e sh_div_strategy = SH_DIV_STRATEGY_DEFAULT;
/* This defines the storage for the variable part of a -mboard= option.
diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h
index 7f541fb..44b9c93 100644
--- a/gcc/config/sh/sh.h
+++ b/gcc/config/sh/sh.h
@@ -1604,6 +1604,7 @@ extern enum reg_class reg_class_from_letter[];
? GENERAL_REGS \
: (CLASS)) \
+#if 0
#define SECONDARY_INOUT_RELOAD_CLASS(CLASS,MODE,X,ELSE) \
((((REGCLASS_HAS_FP_REG (CLASS) \
&& (GET_CODE (X) == REG \
@@ -1675,6 +1676,9 @@ extern enum reg_class reg_class_from_letter[];
&& (GET_CODE (X) == LABEL_REF || PIC_DIRECT_ADDR_P (X))) \
? TARGET_REGS \
: SECONDARY_INOUT_RELOAD_CLASS((CLASS),(MODE),(X), NO_REGS))
+#else
+#define HAVE_SECONDARY_RELOADS
+#endif
/* Return the maximum number of consecutive registers
needed to represent mode MODE in a register of class CLASS.
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index 42e05bc..91e8ff8 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -5845,15 +5845,15 @@ label:
(clobber (scratch:SI))])]
"")
-(define_expand "reload_indf"
- [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
+(define_expand "reload_indf__frn"
+ [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
(match_operand:DF 1 "immediate_operand" "FQ"))
(use (reg:PSI FPSCR_REG))
(clobber (match_operand:SI 2 "register_operand" "=&z"))])]
"TARGET_SH1"
"")
-(define_expand "reload_outdf"
+(define_expand "reload_outdf__RnFRm"
[(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
(match_operand:DF 1 "register_operand" "af,r"))
(clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
@@ -6475,7 +6475,7 @@ label:
[(set_attr "length" "0")
(set_attr "type" "nil")])
-(define_expand "reload_insf"
+(define_expand "reload_insf__frn"
[(parallel [(set (match_operand:SF 0 "register_operand" "=a")
(match_operand:SF 1 "immediate_operand" "FQ"))
(use (reg:PSI FPSCR_REG))
@@ -6483,7 +6483,7 @@ label:
"TARGET_SH1"
"")
-(define_expand "reload_insi"
+(define_expand "reload_insi__i_fpul"
[(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
(match_operand:SI 1 "immediate_operand" "i"))
(clobber (match_operand:SI 2 "register_operand" "=&z"))])]