diff options
author | J"orn Rennecke <joern.rennecke@st.com> | 2005-11-24 18:55:53 +0000 |
---|---|---|
committer | Joern Rennecke <amylaar@gcc.gnu.org> | 2005-11-24 18:55:53 +0000 |
commit | 8a99f6f92fd255690cdc0a1712c7c2f7e1bdcfe8 (patch) | |
tree | c4e97f2cd689b954ad779a8f0f2c7757912a91f8 /gcc/config/sh | |
parent | 1a598a979ba864052b8a922d957c038493411e47 (diff) | |
download | gcc-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.h | 4 | ||||
-rw-r--r-- | gcc/config/sh/sh.c | 103 | ||||
-rw-r--r-- | gcc/config/sh/sh.h | 4 | ||||
-rw-r--r-- | gcc/config/sh/sh.md | 10 |
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"))])] |