aboutsummaryrefslogtreecommitdiff
path: root/gcc/targhooks.c
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/targhooks.c
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/targhooks.c')
-rw-r--r--gcc/targhooks.c86
1 files changed, 86 insertions, 0 deletions
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index 94469a7..1d5a7fe 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -63,6 +63,9 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
#include "target-def.h"
#include "ggc.h"
#include "hard-reg-set.h"
+#include "reload.h"
+#include "optabs.h"
+#include "recog.h"
void
@@ -455,4 +458,87 @@ default_internal_arg_pointer (void)
return virtual_incoming_args_rtx;
}
+enum reg_class
+default_secondary_reload (bool in_p ATTRIBUTE_UNUSED, rtx x ATTRIBUTE_UNUSED,
+ enum reg_class reload_class ATTRIBUTE_UNUSED,
+ enum machine_mode reload_mode ATTRIBUTE_UNUSED,
+ secondary_reload_info *sri)
+{
+ enum reg_class class = NO_REGS;
+
+ if (sri->prev_sri && sri->prev_sri->t_icode != CODE_FOR_nothing)
+ {
+ sri->icode = sri->prev_sri->t_icode;
+ return NO_REGS;
+ }
+#ifdef SECONDARY_INPUT_RELOAD_CLASS
+ if (in_p)
+ class = SECONDARY_INPUT_RELOAD_CLASS (reload_class, reload_mode, x);
+#endif
+#ifdef SECONDARY_OUTPUT_RELOAD_CLASS
+ if (! in_p)
+ class = SECONDARY_OUTPUT_RELOAD_CLASS (reload_class, reload_mode, x);
+#endif
+ if (class != NO_REGS)
+ {
+ enum insn_code icode = (in_p ? reload_in_optab[(int) reload_mode]
+ : reload_out_optab[(int) reload_mode]);
+
+ if (icode != CODE_FOR_nothing
+ && insn_data[(int) icode].operand[in_p].predicate
+ && ! insn_data[(int) icode].operand[in_p].predicate (x, reload_mode))
+ icode = CODE_FOR_nothing;
+ else if (icode != CODE_FOR_nothing)
+ {
+ const char *insn_constraint, *scratch_constraint;
+ char insn_letter, scratch_letter;
+ enum reg_class insn_class, scratch_class;
+
+ gcc_assert (insn_data[(int) icode].n_operands == 3);
+ insn_constraint = insn_data[(int) icode].operand[!in_p].constraint;
+ if (!*insn_constraint)
+ insn_class = ALL_REGS;
+ else
+ {
+ if (in_p)
+ {
+ gcc_assert (*insn_constraint == '=');
+ insn_constraint++;
+ }
+ insn_letter = *insn_constraint;
+ insn_class
+ = (insn_letter == 'r' ? GENERAL_REGS
+ : REG_CLASS_FROM_CONSTRAINT ((unsigned char) insn_letter,
+ insn_constraint));
+ gcc_assert (insn_class != NO_REGS);
+ }
+
+ scratch_constraint = insn_data[(int) icode].operand[2].constraint;
+ /* The scratch register's constraint must start with "=&". */
+ gcc_assert (scratch_constraint[0] == '='
+ && scratch_constraint[1] == '&');
+ scratch_constraint += 2;
+ scratch_letter = *scratch_constraint;
+ scratch_class
+ = (scratch_letter == 'r' ? GENERAL_REGS
+ : REG_CLASS_FROM_CONSTRAINT ((unsigned char) scratch_letter,
+ scratch_constraint));
+
+ if (reg_class_subset_p (reload_class, insn_class))
+ {
+ gcc_assert (scratch_class == class);
+ class = NO_REGS;
+ }
+ else
+ class = insn_class;
+
+ }
+ if (class == NO_REGS)
+ sri->icode = icode;
+ else
+ sri->t_icode = icode;
+ }
+ return class;
+}
+
#include "gt-targhooks.h"