bfin-protos.h (bfin_dsp_memref_p): Declare.
* config/bfin/bfin-protos.h (bfin_dsp_memref_p): Declare. * config/bfin/bfin.c (bfin_dsp_memref_p): New function. (bfin_valid_reg_p): Test for pseudos explicitly and use only REGNO_MODE_CODE_OK_FOR_BASE_P. New args MODE and OUTER_CODE; all callers changed. * config/bfin/bfin.h (PREG_P): Use P_REGNO_P. (IREG_P, P_REGNO_P, I_REGNO_P): New macros. (enum reg_class, REG_CLASS_CONTENTS): Add IPREGS. (BASE_REG_CLASS, REG_OK_FOR_BASE_P, REG_OK_FOR_INDEX_P, REGNO_OK_FOR_BASE_STRICT_P, REGNO_OK_FOR_BASE_NONSTRICT_P): Delete macros. (IREG_POSSIBLE_P, MODE_CODE_BASE_REG_CLASS, REGNO_MODE_CODE_OK_FOR_BASE_P): New macros. (REGNO_REG_CLASS): ARGP is in PREGS. * config/bfin/bfin.md (movhi_insn): Allow for addresses containing IREGS. (zero_extendhisi2, extendhisi2): Likewise; changed to define_and_split to deal with those addresses. * addresses.h: New file. * caller-save.c: Include "addresses.h". (init_caller_save): Use new base_reg_class function. * rtl-factoring.c: Include "addresses.h". (recompute_gain_for_pattern_seq): Use new function ok_for_base_p_1. * recog.c: Include "addresses.h". (preprocess_constraints): Use new base_reg_class function. * regrename.c: Include "addresses.h". (scan_rtx_address): Use new regno_ok_for_base_p and base_reg_class functions. Keep track of a new var INDEX_CODE to compute valid classes. (replace_oldest_value_addr): Likewise. (replace_oldest_value_mem): Use base_reg_class. * reload.c: Include "addresses.h". (REGNO_MODE_OK_FOR_BASE_P, REG_MODE_OK_FOR_BASE_P): Delete macros. (find_reloads): Use new base_reg_class function. (find_reloads_address): Likewise; also use regno_ok_for_base_p. (find_reloads_address_1): Likewise. New args OUTER_CODE and INDEX_CODE; all callers and prototype changed. * reload1.c: Include "addresses.h". (maybe_fix_stack_asms): Use base_reg_class. * regclass.c: Include "addresses.h". (ok_for_index_p_nonstrict, ok_for_base_p_nonstrict): New functions. (init_reg_autoinc): Use new base_reg_class function. (record_reg_classes): Likewise. (record_address_regs): Delete arg CLASS; add args CONTEXT, MODE, OUTER_CODE and INDEX_CODE. All callers and prototype changed. Use new args to compute necessary class. * Makefile.in (regclass.o, reload.o, reload1.o, caller-save.o, recog.o, regrename.o, rtl-factoring.o): Update dependencies. * doc/tm.texi (MODE_CODE_BASE_REG_CLASS): Document. (REGNO_MODE_CODE_OK_FOR_BASE_P): Likewise. (REG_OK_FOR_BASE_P, REG_MODE_OK_FOR_BASE_P, REG_MODE_OK_FOR_REG_BASE_P, REG_OK_FOR_INDEX_P): Delete documentation. From-SVN: r112248
This commit is contained in:
parent
0002d5d2bc
commit
c4963a0a32
@ -1,3 +1,59 @@
|
|||||||
|
2006-03-21 Bernd Schmidt <bernd.schmidt@analog.com>
|
||||||
|
|
||||||
|
* config/bfin/bfin-protos.h (bfin_dsp_memref_p): Declare.
|
||||||
|
* config/bfin/bfin.c (bfin_dsp_memref_p): New function.
|
||||||
|
(bfin_valid_reg_p): Test for pseudos explicitly and use only
|
||||||
|
REGNO_MODE_CODE_OK_FOR_BASE_P. New args MODE and OUTER_CODE; all
|
||||||
|
callers changed.
|
||||||
|
* config/bfin/bfin.h (PREG_P): Use P_REGNO_P.
|
||||||
|
(IREG_P, P_REGNO_P, I_REGNO_P): New macros.
|
||||||
|
(enum reg_class, REG_CLASS_CONTENTS): Add IPREGS.
|
||||||
|
(BASE_REG_CLASS, REG_OK_FOR_BASE_P, REG_OK_FOR_INDEX_P,
|
||||||
|
REGNO_OK_FOR_BASE_STRICT_P, REGNO_OK_FOR_BASE_NONSTRICT_P): Delete
|
||||||
|
macros.
|
||||||
|
(IREG_POSSIBLE_P, MODE_CODE_BASE_REG_CLASS,
|
||||||
|
REGNO_MODE_CODE_OK_FOR_BASE_P): New macros.
|
||||||
|
(REGNO_REG_CLASS): ARGP is in PREGS.
|
||||||
|
* config/bfin/bfin.md (movhi_insn): Allow for addresses containing
|
||||||
|
IREGS.
|
||||||
|
(zero_extendhisi2, extendhisi2): Likewise; changed to define_and_split
|
||||||
|
to deal with those addresses.
|
||||||
|
* addresses.h: New file.
|
||||||
|
* caller-save.c: Include "addresses.h".
|
||||||
|
(init_caller_save): Use new base_reg_class function.
|
||||||
|
* rtl-factoring.c: Include "addresses.h".
|
||||||
|
(recompute_gain_for_pattern_seq): Use new function ok_for_base_p_1.
|
||||||
|
* recog.c: Include "addresses.h".
|
||||||
|
(preprocess_constraints): Use new base_reg_class function.
|
||||||
|
* regrename.c: Include "addresses.h".
|
||||||
|
(scan_rtx_address): Use new regno_ok_for_base_p and base_reg_class
|
||||||
|
functions. Keep track of a new var INDEX_CODE to compute valid
|
||||||
|
classes.
|
||||||
|
(replace_oldest_value_addr): Likewise.
|
||||||
|
(replace_oldest_value_mem): Use base_reg_class.
|
||||||
|
* reload.c: Include "addresses.h".
|
||||||
|
(REGNO_MODE_OK_FOR_BASE_P, REG_MODE_OK_FOR_BASE_P): Delete macros.
|
||||||
|
(find_reloads): Use new base_reg_class function.
|
||||||
|
(find_reloads_address): Likewise; also use regno_ok_for_base_p.
|
||||||
|
(find_reloads_address_1): Likewise. New args OUTER_CODE and INDEX_CODE;
|
||||||
|
all callers and prototype changed.
|
||||||
|
* reload1.c: Include "addresses.h".
|
||||||
|
(maybe_fix_stack_asms): Use base_reg_class.
|
||||||
|
* regclass.c: Include "addresses.h".
|
||||||
|
(ok_for_index_p_nonstrict, ok_for_base_p_nonstrict): New functions.
|
||||||
|
(init_reg_autoinc): Use new base_reg_class function.
|
||||||
|
(record_reg_classes): Likewise.
|
||||||
|
(record_address_regs): Delete arg CLASS; add args CONTEXT, MODE,
|
||||||
|
OUTER_CODE and INDEX_CODE. All callers and prototype changed.
|
||||||
|
Use new args to compute necessary class.
|
||||||
|
|
||||||
|
* Makefile.in (regclass.o, reload.o, reload1.o, caller-save.o, recog.o,
|
||||||
|
regrename.o, rtl-factoring.o): Update dependencies.
|
||||||
|
* doc/tm.texi (MODE_CODE_BASE_REG_CLASS): Document.
|
||||||
|
(REGNO_MODE_CODE_OK_FOR_BASE_P): Likewise.
|
||||||
|
(REG_OK_FOR_BASE_P, REG_MODE_OK_FOR_BASE_P, REG_MODE_OK_FOR_REG_BASE_P,
|
||||||
|
REG_OK_FOR_INDEX_P): Delete documentation.
|
||||||
|
|
||||||
2006-03-21 Alexey Starovoytov <alexey.starovoytov@sun.com>
|
2006-03-21 Alexey Starovoytov <alexey.starovoytov@sun.com>
|
||||||
|
|
||||||
* config.gcc (sparc-*-solaris2*): Change the default CPU setting
|
* config.gcc (sparc-*-solaris2*): Change the default CPU setting
|
||||||
|
@ -1916,7 +1916,7 @@ tree-cfgcleanup.o : tree-cfgcleanup.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
|
|||||||
tree-ssa-propagate.h
|
tree-ssa-propagate.h
|
||||||
rtl-factoring.o : rtl-factoring.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \
|
rtl-factoring.o : rtl-factoring.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \
|
||||||
coretypes.h $(TM_H) $(BASIC_BLOCK_H) $(GGC_H) $(REGS_H) $(PARAMS_H) $(EXPR_H) \
|
coretypes.h $(TM_H) $(BASIC_BLOCK_H) $(GGC_H) $(REGS_H) $(PARAMS_H) $(EXPR_H) \
|
||||||
$(TM_P_H) tree-pass.h tree-flow.h timevar.h output.h
|
addresses.h $(TM_P_H) tree-pass.h tree-flow.h timevar.h output.h
|
||||||
tree-tailcall.o : tree-tailcall.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
|
tree-tailcall.o : tree-tailcall.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
|
||||||
$(RTL_H) $(TREE_H) $(TM_P_H) $(FUNCTION_H) $(TM_H) coretypes.h \
|
$(RTL_H) $(TREE_H) $(TM_P_H) $(FUNCTION_H) $(TM_H) coretypes.h \
|
||||||
$(TREE_DUMP_H) $(DIAGNOSTIC_H) except.h tree-pass.h $(FLAGS_H) langhooks.h \
|
$(TREE_DUMP_H) $(DIAGNOSTIC_H) except.h tree-pass.h $(FLAGS_H) langhooks.h \
|
||||||
@ -2468,11 +2468,12 @@ vec.o : vec.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) coretypes.h vec.h $(GGC_H) \
|
|||||||
reload.o : reload.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
|
reload.o : reload.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
|
||||||
$(FLAGS_H) output.h $(EXPR_H) $(OPTABS_H) reload.h $(RECOG_H) \
|
$(FLAGS_H) output.h $(EXPR_H) $(OPTABS_H) reload.h $(RECOG_H) \
|
||||||
hard-reg-set.h insn-config.h $(REGS_H) $(FUNCTION_H) toplev.h \
|
hard-reg-set.h insn-config.h $(REGS_H) $(FUNCTION_H) toplev.h \
|
||||||
$(TM_P_H) $(PARAMS_H) $(TARGET_H) $(REAL_H)
|
addresses.h $(TM_P_H) $(PARAMS_H) $(TARGET_H) $(REAL_H)
|
||||||
reload1.o : reload1.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
|
reload1.o : reload1.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
|
||||||
$(EXPR_H) $(OPTABS_H) reload.h $(REGS_H) hard-reg-set.h insn-config.h \
|
$(EXPR_H) $(OPTABS_H) reload.h $(REGS_H) hard-reg-set.h insn-config.h \
|
||||||
$(BASIC_BLOCK_H) $(RECOG_H) output.h $(FUNCTION_H) toplev.h $(TM_P_H) \
|
$(BASIC_BLOCK_H) $(RECOG_H) output.h $(FUNCTION_H) toplev.h $(TM_P_H) \
|
||||||
except.h $(TREE_H) $(REAL_H) $(FLAGS_H) $(MACHMODE_H) $(OBSTACK_H)
|
addresses.h except.h $(TREE_H) $(REAL_H) $(FLAGS_H) $(MACHMODE_H) \
|
||||||
|
$(OBSTACK_H)
|
||||||
rtlhooks.o : rtlhooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
|
rtlhooks.o : rtlhooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
|
||||||
rtlhooks-def.h $(EXPR_H) $(RECOG_H)
|
rtlhooks-def.h $(EXPR_H) $(RECOG_H)
|
||||||
postreload.o : postreload.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
postreload.o : postreload.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
||||||
@ -2487,7 +2488,7 @@ postreload-gcse.o : postreload-gcse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
|
|||||||
$(PARAMS_H) timevar.h tree-pass.h $(REAL_H)
|
$(PARAMS_H) timevar.h tree-pass.h $(REAL_H)
|
||||||
caller-save.o : caller-save.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
|
caller-save.o : caller-save.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
|
||||||
$(FLAGS_H) $(REGS_H) hard-reg-set.h insn-config.h $(BASIC_BLOCK_H) $(FUNCTION_H) \
|
$(FLAGS_H) $(REGS_H) hard-reg-set.h insn-config.h $(BASIC_BLOCK_H) $(FUNCTION_H) \
|
||||||
$(RECOG_H) reload.h $(EXPR_H) toplev.h $(TM_P_H)
|
addresses.h $(RECOG_H) reload.h $(EXPR_H) toplev.h $(TM_P_H)
|
||||||
bt-load.o : bt-load.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) except.h \
|
bt-load.o : bt-load.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) except.h \
|
||||||
$(RTL_H) hard-reg-set.h $(REGS_H) $(TM_P_H) $(FIBHEAP_H) output.h $(EXPR_H) \
|
$(RTL_H) hard-reg-set.h $(REGS_H) $(TM_P_H) $(FIBHEAP_H) output.h $(EXPR_H) \
|
||||||
$(TARGET_H) $(FLAGS_H) $(INSN_ATTR_H) $(FUNCTION_H) tree-pass.h toplev.h
|
$(TARGET_H) $(FLAGS_H) $(INSN_ATTR_H) $(FUNCTION_H) tree-pass.h toplev.h
|
||||||
@ -2543,7 +2544,7 @@ final.o : final.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
|
|||||||
recog.o : recog.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
|
recog.o : recog.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
|
||||||
$(FUNCTION_H) $(BASIC_BLOCK_H) $(REGS_H) $(RECOG_H) $(EXPR_H) \
|
$(FUNCTION_H) $(BASIC_BLOCK_H) $(REGS_H) $(RECOG_H) $(EXPR_H) \
|
||||||
$(FLAGS_H) insn-config.h $(INSN_ATTR_H) toplev.h output.h reload.h \
|
$(FLAGS_H) insn-config.h $(INSN_ATTR_H) toplev.h output.h reload.h \
|
||||||
$(TM_P_H) timevar.h tree-pass.h hard-reg-set.h $(REAL_H)
|
addresses.h $(TM_P_H) timevar.h tree-pass.h hard-reg-set.h $(REAL_H)
|
||||||
reg-stack.o : reg-stack.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
reg-stack.o : reg-stack.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
||||||
$(RTL_H) $(TREE_H) $(RECOG_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) \
|
$(RTL_H) $(TREE_H) $(RECOG_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) \
|
||||||
insn-config.h toplev.h reload.h $(FUNCTION_H) $(TM_P_H) $(GGC_H) \
|
insn-config.h toplev.h reload.h $(FUNCTION_H) $(TM_P_H) $(GGC_H) \
|
||||||
@ -2575,7 +2576,7 @@ timevar.o : timevar.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
|||||||
regrename.o : regrename.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
regrename.o : regrename.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
||||||
$(RTL_H) insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h \
|
$(RTL_H) insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h \
|
||||||
output.h $(RECOG_H) $(FUNCTION_H) $(OBSTACK_H) $(FLAGS_H) $(TM_P_H) \
|
output.h $(RECOG_H) $(FUNCTION_H) $(OBSTACK_H) $(FLAGS_H) $(TM_P_H) \
|
||||||
reload.h toplev.h timevar.h tree-pass.h
|
addresses.h reload.h toplev.h timevar.h tree-pass.h
|
||||||
ifcvt.o : ifcvt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
|
ifcvt.o : ifcvt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
|
||||||
$(REGS_H) toplev.h $(FLAGS_H) insn-config.h $(FUNCTION_H) $(RECOG_H) \
|
$(REGS_H) toplev.h $(FLAGS_H) insn-config.h $(FUNCTION_H) $(RECOG_H) \
|
||||||
$(TARGET_H) $(BASIC_BLOCK_H) $(EXPR_H) output.h except.h $(TM_P_H) \
|
$(TARGET_H) $(BASIC_BLOCK_H) $(EXPR_H) output.h except.h $(TM_P_H) \
|
||||||
|
81
gcc/addresses.h
Normal file
81
gcc/addresses.h
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/* Inline functions to test validity of reg classes for addressing modes.
|
||||||
|
Copyright (C) 2006 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 2, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING. If not, write to the Free
|
||||||
|
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301, USA. */
|
||||||
|
|
||||||
|
/* Wrapper function to unify target macros MODE_CODE_BASE_REG_CLASS,
|
||||||
|
MODE_BASE_REG_REG_CLASS, MODE_BASE_REG_CLASS and BASE_REG_CLASS.
|
||||||
|
Arguments as for the MODE_CODE_BASE_REG_CLASS macro. */
|
||||||
|
|
||||||
|
static inline enum reg_class
|
||||||
|
base_reg_class (enum machine_mode mode ATTRIBUTE_UNUSED,
|
||||||
|
enum rtx_code outer_code ATTRIBUTE_UNUSED,
|
||||||
|
enum rtx_code index_code ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
#ifdef MODE_CODE_BASE_REG_CLASS
|
||||||
|
return MODE_CODE_BASE_REG_CLASS (mode, outer_code, index_code);
|
||||||
|
#else
|
||||||
|
#ifdef MODE_BASE_REG_REG_CLASS
|
||||||
|
if (index_code == REG)
|
||||||
|
return MODE_BASE_REG_REG_CLASS (mode);
|
||||||
|
#endif
|
||||||
|
#ifdef MODE_BASE_REG_CLASS
|
||||||
|
return MODE_BASE_REG_CLASS (mode);
|
||||||
|
#else
|
||||||
|
return BASE_REG_CLASS;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wrapper function to unify target macros REGNO_MODE_CODE_OK_FOR_BASE_P,
|
||||||
|
REGNO_MODE_OK_FOR_REG_BASE_P, REGNO_MODE_OK_FOR_BASE_P and
|
||||||
|
REGNO_OK_FOR_BASE_P.
|
||||||
|
Arguments as for the REGNO_MODE_CODE_OK_FOR_BASE_P macro. */
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
ok_for_base_p_1 (unsigned regno, enum machine_mode mode ATTRIBUTE_UNUSED,
|
||||||
|
enum rtx_code outer_code ATTRIBUTE_UNUSED,
|
||||||
|
enum rtx_code index_code ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
#ifdef REGNO_MODE_CODE_OK_FOR_BASE_P
|
||||||
|
return REGNO_MODE_CODE_OK_FOR_BASE_P (regno, mode, outer_code, index_code);
|
||||||
|
#else
|
||||||
|
#ifdef REGNO_MODE_OK_FOR_REG_BASE_P
|
||||||
|
if (index_code == REG)
|
||||||
|
return REGNO_MODE_OK_FOR_REG_BASE_P (regno, mode);
|
||||||
|
#endif
|
||||||
|
#ifdef REGNO_MODE_OK_FOR_BASE_P
|
||||||
|
return REGNO_MODE_OK_FOR_BASE_P (regno, mode);
|
||||||
|
#else
|
||||||
|
return REGNO_OK_FOR_BASE_P (regno);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wrapper around ok_for_base_p_1, for use after register allocation is
|
||||||
|
complete. Arguments as for the called function. */
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
regno_ok_for_base_p (unsigned regno, enum machine_mode mode,
|
||||||
|
enum rtx_code outer_code, enum rtx_code index_code)
|
||||||
|
{
|
||||||
|
if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] >= 0)
|
||||||
|
regno = reg_renumber[regno];
|
||||||
|
|
||||||
|
return ok_for_base_p_1 (regno, mode, outer_code, index_code);
|
||||||
|
}
|
@ -25,6 +25,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
|||||||
#include "tm.h"
|
#include "tm.h"
|
||||||
#include "rtl.h"
|
#include "rtl.h"
|
||||||
#include "regs.h"
|
#include "regs.h"
|
||||||
|
#include "addresses.h"
|
||||||
#include "insn-config.h"
|
#include "insn-config.h"
|
||||||
#include "flags.h"
|
#include "flags.h"
|
||||||
#include "hard-reg-set.h"
|
#include "hard-reg-set.h"
|
||||||
@ -153,7 +154,7 @@ init_caller_save (void)
|
|||||||
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
|
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
|
||||||
if (TEST_HARD_REG_BIT
|
if (TEST_HARD_REG_BIT
|
||||||
(reg_class_contents
|
(reg_class_contents
|
||||||
[(int) MODE_BASE_REG_CLASS (regno_save_mode [i][1])], i))
|
[(int) base_reg_class (regno_save_mode [i][1], PLUS, CONST_INT)], i))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
gcc_assert (i < FIRST_PSEUDO_REGISTER);
|
gcc_assert (i < FIRST_PSEUDO_REGISTER);
|
||||||
|
@ -47,6 +47,7 @@ extern rtx bfin_gen_compare (rtx, Mmode);
|
|||||||
extern void expand_move (rtx *, Mmode);
|
extern void expand_move (rtx *, Mmode);
|
||||||
extern void bfin_expand_call (rtx, rtx, rtx, rtx, int);
|
extern void bfin_expand_call (rtx, rtx, rtx, rtx, int);
|
||||||
extern bool bfin_longcall_p (rtx, int);
|
extern bool bfin_longcall_p (rtx, int);
|
||||||
|
extern bool bfin_dsp_memref_p (rtx);
|
||||||
extern bool bfin_expand_strmov (rtx, rtx, rtx, rtx);
|
extern bool bfin_expand_strmov (rtx, rtx, rtx, rtx);
|
||||||
|
|
||||||
extern void conditional_register_usage (void);
|
extern void conditional_register_usage (void);
|
||||||
|
@ -1062,6 +1062,19 @@ effective_address_32bit_p (rtx op, enum machine_mode mode)
|
|||||||
return offset < 0 || offset > 30;
|
return offset < 0 || offset > 30;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Returns true if X is a memory reference using an I register. */
|
||||||
|
bool
|
||||||
|
bfin_dsp_memref_p (rtx x)
|
||||||
|
{
|
||||||
|
if (! MEM_P (x))
|
||||||
|
return false;
|
||||||
|
x = XEXP (x, 0);
|
||||||
|
if (GET_CODE (x) == POST_INC || GET_CODE (x) == PRE_INC
|
||||||
|
|| GET_CODE (x) == POST_DEC || GET_CODE (x) == PRE_DEC)
|
||||||
|
x = XEXP (x, 0);
|
||||||
|
return IREG_P (x);
|
||||||
|
}
|
||||||
|
|
||||||
/* Return cost of the memory address ADDR.
|
/* Return cost of the memory address ADDR.
|
||||||
All addressing modes are equally cheap on the Blackfin. */
|
All addressing modes are equally cheap on the Blackfin. */
|
||||||
|
|
||||||
@ -2100,10 +2113,13 @@ bfin_valid_add (enum machine_mode mode, HOST_WIDE_INT value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
bfin_valid_reg_p (unsigned int regno, int strict)
|
bfin_valid_reg_p (unsigned int regno, int strict, enum machine_mode mode,
|
||||||
|
enum rtx_code outer_code)
|
||||||
{
|
{
|
||||||
return ((strict && REGNO_OK_FOR_BASE_STRICT_P (regno))
|
if (strict)
|
||||||
|| (!strict && REGNO_OK_FOR_BASE_NONSTRICT_P (regno)));
|
return REGNO_OK_FOR_BASE_STRICT_P (regno, mode, outer_code, SCRATCH);
|
||||||
|
else
|
||||||
|
return REGNO_OK_FOR_BASE_NONSTRICT_P (regno, mode, outer_code, SCRATCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -2111,12 +2127,12 @@ bfin_legitimate_address_p (enum machine_mode mode, rtx x, int strict)
|
|||||||
{
|
{
|
||||||
switch (GET_CODE (x)) {
|
switch (GET_CODE (x)) {
|
||||||
case REG:
|
case REG:
|
||||||
if (bfin_valid_reg_p (REGNO (x), strict))
|
if (bfin_valid_reg_p (REGNO (x), strict, mode, MEM))
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
case PLUS:
|
case PLUS:
|
||||||
if (REG_P (XEXP (x, 0))
|
if (REG_P (XEXP (x, 0))
|
||||||
&& bfin_valid_reg_p (REGNO (XEXP (x, 0)), strict)
|
&& bfin_valid_reg_p (REGNO (XEXP (x, 0)), strict, mode, PLUS)
|
||||||
&& (GET_CODE (XEXP (x, 1)) == UNSPEC
|
&& (GET_CODE (XEXP (x, 1)) == UNSPEC
|
||||||
|| (GET_CODE (XEXP (x, 1)) == CONST_INT
|
|| (GET_CODE (XEXP (x, 1)) == CONST_INT
|
||||||
&& bfin_valid_add (mode, INTVAL (XEXP (x, 1))))))
|
&& bfin_valid_add (mode, INTVAL (XEXP (x, 1))))))
|
||||||
@ -2126,13 +2142,13 @@ bfin_legitimate_address_p (enum machine_mode mode, rtx x, int strict)
|
|||||||
case POST_DEC:
|
case POST_DEC:
|
||||||
if (LEGITIMATE_MODE_FOR_AUTOINC_P (mode)
|
if (LEGITIMATE_MODE_FOR_AUTOINC_P (mode)
|
||||||
&& REG_P (XEXP (x, 0))
|
&& REG_P (XEXP (x, 0))
|
||||||
&& bfin_valid_reg_p (REGNO (XEXP (x, 0)), strict))
|
&& bfin_valid_reg_p (REGNO (XEXP (x, 0)), strict, mode, POST_INC))
|
||||||
return true;
|
return true;
|
||||||
case PRE_DEC:
|
case PRE_DEC:
|
||||||
if (LEGITIMATE_MODE_FOR_AUTOINC_P (mode)
|
if (LEGITIMATE_MODE_FOR_AUTOINC_P (mode)
|
||||||
&& XEXP (x, 0) == stack_pointer_rtx
|
&& XEXP (x, 0) == stack_pointer_rtx
|
||||||
&& REG_P (XEXP (x, 0))
|
&& REG_P (XEXP (x, 0))
|
||||||
&& bfin_valid_reg_p (REGNO (XEXP (x, 0)), strict))
|
&& bfin_valid_reg_p (REGNO (XEXP (x, 0)), strict, mode, PRE_DEC))
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -215,9 +215,13 @@ extern const char *bfin_library_id_string;
|
|||||||
|
|
||||||
#define FIRST_PSEUDO_REGISTER 44
|
#define FIRST_PSEUDO_REGISTER 44
|
||||||
|
|
||||||
#define PREG_P(X) (REG_P (X) && REGNO (X) >= REG_P0 && REGNO (X) <= REG_P7)
|
#define PREG_P(X) (REG_P (X) && P_REGNO_P (REGNO (X)))
|
||||||
|
#define IREG_P(X) (REG_P (X) && I_REGNO_P (REGNO (X)))
|
||||||
#define ADDRESS_REGNO_P(X) ((X) >= REG_P0 && (X) <= REG_M3)
|
#define ADDRESS_REGNO_P(X) ((X) >= REG_P0 && (X) <= REG_M3)
|
||||||
#define D_REGNO_P(X) ((X) <= REG_R7)
|
#define D_REGNO_P(X) ((X) <= REG_R7)
|
||||||
|
#define P_REGNO_P(X) ((X) >= REG_P0 && (X) <= REG_P7)
|
||||||
|
#define I_REGNO_P(X) \
|
||||||
|
((X) == REG_I0 || (X) == REG_I1 || (X) == REG_I2 || (X) == REG_I3)
|
||||||
|
|
||||||
#define REGISTER_NAMES { \
|
#define REGISTER_NAMES { \
|
||||||
"R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", \
|
"R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", \
|
||||||
@ -344,6 +348,7 @@ enum reg_class
|
|||||||
DREGS,
|
DREGS,
|
||||||
PREGS_CLOBBERED,
|
PREGS_CLOBBERED,
|
||||||
PREGS,
|
PREGS,
|
||||||
|
IPREGS,
|
||||||
DPREGS,
|
DPREGS,
|
||||||
MOST_REGS,
|
MOST_REGS,
|
||||||
PROLOGUE_REGS,
|
PROLOGUE_REGS,
|
||||||
@ -374,6 +379,7 @@ enum reg_class
|
|||||||
"DREGS", \
|
"DREGS", \
|
||||||
"PREGS_CLOBBERED", \
|
"PREGS_CLOBBERED", \
|
||||||
"PREGS", \
|
"PREGS", \
|
||||||
|
"IPREGS", \
|
||||||
"DPREGS", \
|
"DPREGS", \
|
||||||
"MOST_REGS", \
|
"MOST_REGS", \
|
||||||
"PROLOGUE_REGS", \
|
"PROLOGUE_REGS", \
|
||||||
@ -412,27 +418,40 @@ enum reg_class
|
|||||||
{ 0x000000ff, 0 }, /* DREGS */ \
|
{ 0x000000ff, 0 }, /* DREGS */ \
|
||||||
{ 0x00004700, 0x800 }, /* PREGS_CLOBBERED */ \
|
{ 0x00004700, 0x800 }, /* PREGS_CLOBBERED */ \
|
||||||
{ 0x0000ff00, 0x800 }, /* PREGS */ \
|
{ 0x0000ff00, 0x800 }, /* PREGS */ \
|
||||||
|
{ 0x000fff00, 0x800 }, /* IPREGS */ \
|
||||||
{ 0x0000ffff, 0x800 }, /* DPREGS */ \
|
{ 0x0000ffff, 0x800 }, /* DPREGS */ \
|
||||||
{ 0xffffffff, 0x800 }, /* MOST_REGS */\
|
{ 0xffffffff, 0x800 }, /* MOST_REGS */\
|
||||||
{ 0x00000000, 0x7f8 }, /* PROLOGUE_REGS */\
|
{ 0x00000000, 0x7f8 }, /* PROLOGUE_REGS */\
|
||||||
{ 0xffffffff, 0xff8 }, /* NON_A_CC_REGS */\
|
{ 0xffffffff, 0xff8 }, /* NON_A_CC_REGS */\
|
||||||
{ 0xffffffff, 0xfff }} /* ALL_REGS */
|
{ 0xffffffff, 0xfff }} /* ALL_REGS */
|
||||||
|
|
||||||
#define BASE_REG_CLASS PREGS
|
#define IREG_POSSIBLE_P(OUTER) \
|
||||||
|
((OUTER) == POST_INC || (OUTER) == PRE_INC \
|
||||||
|
|| (OUTER) == POST_DEC || (OUTER) == PRE_DEC \
|
||||||
|
|| (OUTER) == MEM || (OUTER) == ADDRESS)
|
||||||
|
|
||||||
|
#define MODE_CODE_BASE_REG_CLASS(MODE, OUTER, INDEX) \
|
||||||
|
((MODE) == HImode && IREG_POSSIBLE_P (OUTER) ? IPREGS : PREGS)
|
||||||
|
|
||||||
#define INDEX_REG_CLASS PREGS
|
#define INDEX_REG_CLASS PREGS
|
||||||
|
|
||||||
#define REGNO_OK_FOR_BASE_STRICT_P(X) (REGNO_REG_CLASS (X) == BASE_REG_CLASS)
|
#define REGNO_OK_FOR_BASE_STRICT_P(X, MODE, OUTER, INDEX) \
|
||||||
#define REGNO_OK_FOR_BASE_NONSTRICT_P(X) \
|
(P_REGNO_P (X) || (X) == REG_ARGP \
|
||||||
(((X) >= FIRST_PSEUDO_REGISTER) || REGNO_REG_CLASS (X) == BASE_REG_CLASS)
|
|| (IREG_POSSIBLE_P (OUTER) && (MODE) == HImode \
|
||||||
|
&& I_REGNO_P (X)))
|
||||||
|
|
||||||
|
#define REGNO_OK_FOR_BASE_NONSTRICT_P(X, MODE, OUTER, INDEX) \
|
||||||
|
((X) >= FIRST_PSEUDO_REGISTER \
|
||||||
|
|| REGNO_OK_FOR_BASE_STRICT_P (X, MODE, OUTER, INDEX))
|
||||||
|
|
||||||
#ifdef REG_OK_STRICT
|
#ifdef REG_OK_STRICT
|
||||||
#define REGNO_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_STRICT_P (X)
|
#define REGNO_MODE_CODE_OK_FOR_BASE_P(X, MODE, OUTER, INDEX) \
|
||||||
|
REGNO_OK_FOR_BASE_STRICT_P (X, MODE, OUTER, INDEX)
|
||||||
#else
|
#else
|
||||||
#define REGNO_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_NONSTRICT_P (X)
|
#define REGNO_MODE_CODE_OK_FOR_BASE_P(X, MODE, OUTER, INDEX) \
|
||||||
|
REGNO_OK_FOR_BASE_NONSTRICT_P (X, MODE, OUTER, INDEX)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define REG_OK_FOR_BASE_P(X) (REG_P (X) && REGNO_OK_FOR_BASE_P (REGNO (X)))
|
|
||||||
#define REG_OK_FOR_INDEX_P(X) 0
|
|
||||||
#define REGNO_OK_FOR_INDEX_P(X) 0
|
#define REGNO_OK_FOR_INDEX_P(X) 0
|
||||||
|
|
||||||
/* Get reg_class from a letter such as appears in the machine description. */
|
/* Get reg_class from a letter such as appears in the machine description. */
|
||||||
@ -464,7 +483,7 @@ enum reg_class
|
|||||||
#define REGNO_REG_CLASS(REGNO) \
|
#define REGNO_REG_CLASS(REGNO) \
|
||||||
((REGNO) < REG_P0 ? DREGS \
|
((REGNO) < REG_P0 ? DREGS \
|
||||||
: (REGNO) < REG_I0 ? PREGS \
|
: (REGNO) < REG_I0 ? PREGS \
|
||||||
: (REGNO) == REG_ARGP ? BASE_REG_CLASS \
|
: (REGNO) == REG_ARGP ? PREGS \
|
||||||
: (REGNO) >= REG_I0 && (REGNO) <= REG_I3 ? IREGS \
|
: (REGNO) >= REG_I0 && (REGNO) <= REG_I3 ? IREGS \
|
||||||
: (REGNO) >= REG_L0 && (REGNO) <= REG_L3 ? LREGS \
|
: (REGNO) >= REG_L0 && (REGNO) <= REG_L3 ? LREGS \
|
||||||
: (REGNO) >= REG_B0 && (REGNO) <= REG_B3 ? BREGS \
|
: (REGNO) >= REG_B0 && (REGNO) <= REG_B3 ? BREGS \
|
||||||
|
@ -418,12 +418,23 @@
|
|||||||
[(set (match_operand:HI 0 "nonimmediate_operand" "=x,da,x,d,mr")
|
[(set (match_operand:HI 0 "nonimmediate_operand" "=x,da,x,d,mr")
|
||||||
(match_operand:HI 1 "general_operand" "x,xKs7,xKsh,mr,d"))]
|
(match_operand:HI 1 "general_operand" "x,xKs7,xKsh,mr,d"))]
|
||||||
"GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
|
"GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
|
||||||
"@
|
{
|
||||||
%0 = %1;
|
static const char *templates[] = {
|
||||||
%0 = %1 (X);
|
"%0 = %1;",
|
||||||
%0 = %1 (X);
|
"%0 = %1 (X);",
|
||||||
%0 = W %1 (X);
|
"%0 = %1 (X);",
|
||||||
W %0 = %1;"
|
"%0 = W %1 (X);",
|
||||||
|
"W %0 = %1;",
|
||||||
|
"%h0 = W %1;",
|
||||||
|
"W %0 = %h1;"
|
||||||
|
};
|
||||||
|
int alt = which_alternative;
|
||||||
|
rtx mem = (MEM_P (operands[0]) ? operands[0]
|
||||||
|
: MEM_P (operands[1]) ? operands[1] : NULL_RTX);
|
||||||
|
if (mem && bfin_dsp_memref_p (mem))
|
||||||
|
alt += 2;
|
||||||
|
return templates[alt];
|
||||||
|
}
|
||||||
[(set_attr "type" "move,mvi,mvi,mcld,mcst")
|
[(set_attr "type" "move,mvi,mvi,mcld,mcst")
|
||||||
(set_attr "length" "2,2,4,*,*")])
|
(set_attr "length" "2,2,4,*,*")])
|
||||||
|
|
||||||
@ -588,22 +599,34 @@
|
|||||||
|
|
||||||
;; Sign and zero extensions
|
;; Sign and zero extensions
|
||||||
|
|
||||||
(define_insn "extendhisi2"
|
(define_insn_and_split "extendhisi2"
|
||||||
[(set (match_operand:SI 0 "register_operand" "=d, d")
|
[(set (match_operand:SI 0 "register_operand" "=d, d")
|
||||||
(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d, m")))]
|
(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d, m")))]
|
||||||
""
|
""
|
||||||
"@
|
"@
|
||||||
%0 = %h1 (X);
|
%0 = %h1 (X);
|
||||||
%0 = W %h1 (X);"
|
%0 = W %h1 (X);"
|
||||||
|
"reload_completed && bfin_dsp_memref_p (operands[1])"
|
||||||
|
[(set (match_dup 2) (match_dup 1))
|
||||||
|
(set (match_dup 0) (sign_extend:SI (match_dup 2)))]
|
||||||
|
{
|
||||||
|
operands[2] = gen_lowpart (HImode, operands[0]);
|
||||||
|
}
|
||||||
[(set_attr "type" "alu0,mcld")])
|
[(set_attr "type" "alu0,mcld")])
|
||||||
|
|
||||||
(define_insn "zero_extendhisi2"
|
(define_insn_and_split "zero_extendhisi2"
|
||||||
[(set (match_operand:SI 0 "register_operand" "=d, d")
|
[(set (match_operand:SI 0 "register_operand" "=d, d")
|
||||||
(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d, m")))]
|
(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d, m")))]
|
||||||
""
|
""
|
||||||
"@
|
"@
|
||||||
%0 = %h1 (Z);
|
%0 = %h1 (Z);
|
||||||
%0 = W%h1 (Z);"
|
%0 = W %h1 (Z);"
|
||||||
|
"reload_completed && bfin_dsp_memref_p (operands[1])"
|
||||||
|
[(set (match_dup 2) (match_dup 1))
|
||||||
|
(set (match_dup 0) (zero_extend:SI (match_dup 2)))]
|
||||||
|
{
|
||||||
|
operands[2] = gen_lowpart (HImode, operands[0]);
|
||||||
|
}
|
||||||
[(set_attr "type" "alu0,mcld")])
|
[(set_attr "type" "alu0,mcld")])
|
||||||
|
|
||||||
(define_insn "zero_extendbisi2"
|
(define_insn "zero_extendbisi2"
|
||||||
|
@ -631,40 +631,6 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
|||||||
#define TARGET_FLOAT_FORMAT IEEE_FLOAT_FORMAT
|
#define TARGET_FLOAT_FORMAT IEEE_FLOAT_FORMAT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Some macros can be defined by the backend in either a mode-dependent
|
|
||||||
or mode-independent form. The compiler proper should only use the
|
|
||||||
mode-dependent form, providing VOIDmode when the mode is unknown.
|
|
||||||
We can't poison the macros because the backend may reference them. */
|
|
||||||
|
|
||||||
#ifndef REGNO_MODE_OK_FOR_BASE_P
|
|
||||||
#define REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE) REGNO_OK_FOR_BASE_P (REGNO)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef REG_MODE_OK_FOR_BASE_P
|
|
||||||
#define REG_MODE_OK_FOR_BASE_P(REG, MODE) REG_OK_FOR_BASE_P (REG)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Determine the register class for registers suitable to be the base
|
|
||||||
address register in a MEM. Allow the choice to be dependent upon
|
|
||||||
the mode of the memory access. */
|
|
||||||
#ifndef MODE_BASE_REG_CLASS
|
|
||||||
#define MODE_BASE_REG_CLASS(MODE) BASE_REG_CLASS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Some machines require a different base register class if the index
|
|
||||||
is a register. By default, assume that a base register is acceptable. */
|
|
||||||
#ifndef MODE_BASE_REG_REG_CLASS
|
|
||||||
#define MODE_BASE_REG_REG_CLASS(MODE) MODE_BASE_REG_CLASS(MODE)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef REGNO_MODE_OK_FOR_REG_BASE_P
|
|
||||||
#define REGNO_MODE_OK_FOR_REG_BASE_P(REGNO, MODE) REGNO_MODE_OK_FOR_BASE_P (REGNO, MODE)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef REG_MODE_OK_FOR_REG_BASE_P
|
|
||||||
#define REG_MODE_OK_FOR_REG_BASE_P(REGNO, MODE) REG_MODE_OK_FOR_BASE_P (REGNO, MODE)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef LARGEST_EXPONENT_IS_NORMAL
|
#ifndef LARGEST_EXPONENT_IS_NORMAL
|
||||||
#define LARGEST_EXPONENT_IS_NORMAL(SIZE) 0
|
#define LARGEST_EXPONENT_IS_NORMAL(SIZE) 0
|
||||||
#endif
|
#endif
|
||||||
|
@ -2294,6 +2294,16 @@ register address. You should define this macro if base plus index
|
|||||||
addresses have different requirements than other base register uses.
|
addresses have different requirements than other base register uses.
|
||||||
@end defmac
|
@end defmac
|
||||||
|
|
||||||
|
@defmac MODE_CODE_BASE_REG_CLASS (@var{mode}, @var{outer_code}, @var{index_code})
|
||||||
|
A C expression whose value is the register class to which a valid
|
||||||
|
base register must belong. @var{outer_code} and @var{index_code} define the
|
||||||
|
context in which the base register occurs. @var{outer_code} is the code of
|
||||||
|
the immediately enclosing expression (@code{MEM} for the top level of an
|
||||||
|
address, @code{ADDRESS} for something that occurs in an
|
||||||
|
@code{address_operand}). @var{index_code} is the code of the corresponding
|
||||||
|
index expression if @var{outer_code} is @code{PLUS}; @code{SCRATCH} otherwise.
|
||||||
|
@end defmac
|
||||||
|
|
||||||
@defmac INDEX_REG_CLASS
|
@defmac INDEX_REG_CLASS
|
||||||
A macro whose definition is the name of the class to which a valid
|
A macro whose definition is the name of the class to which a valid
|
||||||
index register must belong. An index register is one used in an
|
index register must belong. An index register is one used in an
|
||||||
@ -2314,7 +2324,9 @@ that expression may examine the mode of the memory reference in
|
|||||||
@var{mode}. You should define this macro if the mode of the memory
|
@var{mode}. You should define this macro if the mode of the memory
|
||||||
reference affects whether a register may be used as a base register. If
|
reference affects whether a register may be used as a base register. If
|
||||||
you define this macro, the compiler will use it instead of
|
you define this macro, the compiler will use it instead of
|
||||||
@code{REGNO_OK_FOR_BASE_P}.
|
@code{REGNO_OK_FOR_BASE_P}. The mode may be @code{VOIDmode} for addresses
|
||||||
|
that appear outside a @code{MEM}, i.e. as an @code{address_operand}.
|
||||||
|
|
||||||
@end defmac
|
@end defmac
|
||||||
|
|
||||||
@defmac REGNO_MODE_OK_FOR_REG_BASE_P (@var{num}, @var{mode})
|
@defmac REGNO_MODE_OK_FOR_REG_BASE_P (@var{num}, @var{mode})
|
||||||
@ -2324,6 +2336,20 @@ memory in mode @var{mode}. It may be either a suitable hard register or a
|
|||||||
pseudo register that has been allocated such a hard register. You should
|
pseudo register that has been allocated such a hard register. You should
|
||||||
define this macro if base plus index addresses have different requirements
|
define this macro if base plus index addresses have different requirements
|
||||||
than other base register uses.
|
than other base register uses.
|
||||||
|
|
||||||
|
Use of this macro is deprecated; please use the more general
|
||||||
|
@code{REGNO_MODE_CODE_OK_FOR_BASE_P}.
|
||||||
|
@end defmac
|
||||||
|
|
||||||
|
@defmac REGNO_MODE_CODE_OK_FOR_BASE_P (@var{num}, @var{mode}, @var{outer_code}, @var{index_code})
|
||||||
|
A C expression that is just like @code{REGNO_MODE_OK_FOR_BASE_P}, except that
|
||||||
|
that expression may examine the context in which the register appears in the
|
||||||
|
memory reference. @var{outer_code} is the code of the immediately enclosing
|
||||||
|
expression (@code{MEM} if at the top level of the address, @code{ADDRESS} for
|
||||||
|
something that occurs in an @code{address_operand}). @var{index_code} is the
|
||||||
|
code of the corresponding index expression if @var{outer_code} is @code{PLUS};
|
||||||
|
@code{SCRATCH} otherwise. The mode may be @code{VOIDmode} for addresses
|
||||||
|
that appear outside a @code{MEM}, i.e. as an @code{address_operand}.
|
||||||
@end defmac
|
@end defmac
|
||||||
|
|
||||||
@defmac REGNO_OK_FOR_INDEX_P (@var{num})
|
@defmac REGNO_OK_FOR_INDEX_P (@var{num})
|
||||||
@ -5056,48 +5082,6 @@ into the @code{symbol_ref}, and then check for it here. When you see a
|
|||||||
Format}.
|
Format}.
|
||||||
@end defmac
|
@end defmac
|
||||||
|
|
||||||
@defmac REG_OK_FOR_BASE_P (@var{x})
|
|
||||||
A C expression that is nonzero if @var{x} (assumed to be a @code{reg}
|
|
||||||
RTX) is valid for use as a base register. For hard registers, it
|
|
||||||
should always accept those which the hardware permits and reject the
|
|
||||||
others. Whether the macro accepts or rejects pseudo registers must be
|
|
||||||
controlled by @code{REG_OK_STRICT} as described above. This usually
|
|
||||||
requires two variant definitions, of which @code{REG_OK_STRICT}
|
|
||||||
controls the one actually used.
|
|
||||||
@end defmac
|
|
||||||
|
|
||||||
@defmac REG_MODE_OK_FOR_BASE_P (@var{x}, @var{mode})
|
|
||||||
A C expression that is just like @code{REG_OK_FOR_BASE_P}, except that
|
|
||||||
that expression may examine the mode of the memory reference in
|
|
||||||
@var{mode}. You should define this macro if the mode of the memory
|
|
||||||
reference affects whether a register may be used as a base register. If
|
|
||||||
you define this macro, the compiler will use it instead of
|
|
||||||
@code{REG_OK_FOR_BASE_P}.
|
|
||||||
@end defmac
|
|
||||||
|
|
||||||
@defmac REG_MODE_OK_FOR_REG_BASE_P (@var{x}, @var{mode})
|
|
||||||
A C expression which is nonzero if @var{x} (assumed to be a @code{reg} RTX)
|
|
||||||
is suitable for use as a base register in base plus index operand addresses,
|
|
||||||
accessing memory in mode @var{mode}. It may be either a suitable hard
|
|
||||||
register or a pseudo register that has been allocated such a hard register.
|
|
||||||
You should define this macro if base plus index addresses have different
|
|
||||||
requirements than other base register uses.
|
|
||||||
@end defmac
|
|
||||||
|
|
||||||
@defmac REG_OK_FOR_INDEX_P (@var{x})
|
|
||||||
A C expression that is nonzero if @var{x} (assumed to be a @code{reg}
|
|
||||||
RTX) is valid for use as an index register.
|
|
||||||
|
|
||||||
The difference between an index register and a base register is that
|
|
||||||
the index register may be scaled. If an address involves the sum of
|
|
||||||
two registers, neither one of them scaled, then either one may be
|
|
||||||
labeled the ``base'' and the other the ``index''; but whichever
|
|
||||||
labeling is used must fit the machine's constraints of which registers
|
|
||||||
may serve in each capacity. The compiler will try both labelings,
|
|
||||||
looking for one that is valid, and will reload one or both registers
|
|
||||||
only if neither labeling works.
|
|
||||||
@end defmac
|
|
||||||
|
|
||||||
@defmac FIND_BASE_TERM (@var{x})
|
@defmac FIND_BASE_TERM (@var{x})
|
||||||
A C expression to determine the base term of address @var{x}.
|
A C expression to determine the base term of address @var{x}.
|
||||||
This macro is used in only one place: `find_base_term' in alias.c.
|
This macro is used in only one place: `find_base_term' in alias.c.
|
||||||
|
@ -31,6 +31,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
|||||||
#include "hard-reg-set.h"
|
#include "hard-reg-set.h"
|
||||||
#include "recog.h"
|
#include "recog.h"
|
||||||
#include "regs.h"
|
#include "regs.h"
|
||||||
|
#include "addresses.h"
|
||||||
#include "expr.h"
|
#include "expr.h"
|
||||||
#include "function.h"
|
#include "function.h"
|
||||||
#include "flags.h"
|
#include "flags.h"
|
||||||
@ -2157,7 +2158,7 @@ preprocess_constraints (void)
|
|||||||
case 'p':
|
case 'p':
|
||||||
op_alt[j].is_address = 1;
|
op_alt[j].is_address = 1;
|
||||||
op_alt[j].cl = reg_class_subunion[(int) op_alt[j].cl]
|
op_alt[j].cl = reg_class_subunion[(int) op_alt[j].cl]
|
||||||
[(int) MODE_BASE_REG_CLASS (VOIDmode)];
|
[(int) base_reg_class (VOIDmode, ADDRESS, SCRATCH)];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'g':
|
case 'g':
|
||||||
@ -2178,7 +2179,8 @@ preprocess_constraints (void)
|
|||||||
op_alt[j].cl
|
op_alt[j].cl
|
||||||
= (reg_class_subunion
|
= (reg_class_subunion
|
||||||
[(int) op_alt[j].cl]
|
[(int) op_alt[j].cl]
|
||||||
[(int) MODE_BASE_REG_CLASS (VOIDmode)]);
|
[(int) base_reg_class (VOIDmode, ADDRESS,
|
||||||
|
SCRATCH)]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
140
gcc/regclass.c
140
gcc/regclass.c
@ -36,6 +36,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
|||||||
#include "flags.h"
|
#include "flags.h"
|
||||||
#include "basic-block.h"
|
#include "basic-block.h"
|
||||||
#include "regs.h"
|
#include "regs.h"
|
||||||
|
#include "addresses.h"
|
||||||
#include "function.h"
|
#include "function.h"
|
||||||
#include "insn-config.h"
|
#include "insn-config.h"
|
||||||
#include "recog.h"
|
#include "recog.h"
|
||||||
@ -852,12 +853,36 @@ static void record_reg_classes (int, int, rtx *, enum machine_mode *,
|
|||||||
struct reg_pref *);
|
struct reg_pref *);
|
||||||
static int copy_cost (rtx, enum machine_mode, enum reg_class, int,
|
static int copy_cost (rtx, enum machine_mode, enum reg_class, int,
|
||||||
secondary_reload_info *);
|
secondary_reload_info *);
|
||||||
static void record_address_regs (rtx, enum reg_class, int);
|
static void record_address_regs (enum machine_mode, rtx, int, enum rtx_code,
|
||||||
|
enum rtx_code, int);
|
||||||
#ifdef FORBIDDEN_INC_DEC_CLASSES
|
#ifdef FORBIDDEN_INC_DEC_CLASSES
|
||||||
static int auto_inc_dec_reg_p (rtx, enum machine_mode);
|
static int auto_inc_dec_reg_p (rtx, enum machine_mode);
|
||||||
#endif
|
#endif
|
||||||
static void reg_scan_mark_refs (rtx, rtx, int);
|
static void reg_scan_mark_refs (rtx, rtx, int);
|
||||||
|
|
||||||
|
/* Wrapper around REGNO_OK_FOR_INDEX_P, to allow pseudo registers. */
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
ok_for_index_p_nonstrict (rtx reg)
|
||||||
|
{
|
||||||
|
unsigned regno = REGNO (reg);
|
||||||
|
return regno >= FIRST_PSEUDO_REGISTER || REGNO_OK_FOR_INDEX_P (regno);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* A version of regno_ok_for_base_p for use during regclass, when all pseudos
|
||||||
|
should count as OK. Arguments as for regno_ok_for_base_p. */
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
ok_for_base_p_nonstrict (rtx reg, enum machine_mode mode,
|
||||||
|
enum rtx_code outer_code, enum rtx_code index_code)
|
||||||
|
{
|
||||||
|
unsigned regno = REGNO (reg);
|
||||||
|
if (regno >= FIRST_PSEUDO_REGISTER)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return ok_for_base_p_1 (regno, mode, outer_code, index_code);
|
||||||
|
}
|
||||||
|
|
||||||
/* Return the reg_class in which pseudo reg number REGNO is best allocated.
|
/* Return the reg_class in which pseudo reg number REGNO is best allocated.
|
||||||
This function is sometimes called before the info has been computed.
|
This function is sometimes called before the info has been computed.
|
||||||
When that happens, just return GENERAL_REGS, which is innocuous. */
|
When that happens, just return GENERAL_REGS, which is innocuous. */
|
||||||
@ -958,12 +983,13 @@ record_operand_costs (rtx insn, struct costs *op_costs,
|
|||||||
recog_data.operand[i] = SUBREG_REG (recog_data.operand[i]);
|
recog_data.operand[i] = SUBREG_REG (recog_data.operand[i]);
|
||||||
|
|
||||||
if (MEM_P (recog_data.operand[i]))
|
if (MEM_P (recog_data.operand[i]))
|
||||||
record_address_regs (XEXP (recog_data.operand[i], 0),
|
record_address_regs (GET_MODE (recog_data.operand[i]),
|
||||||
MODE_BASE_REG_CLASS (modes[i]), frequency * 2);
|
XEXP (recog_data.operand[i], 0),
|
||||||
|
0, MEM, SCRATCH, frequency * 2);
|
||||||
else if (constraints[i][0] == 'p'
|
else if (constraints[i][0] == 'p'
|
||||||
|| EXTRA_ADDRESS_CONSTRAINT (constraints[i][0], constraints[i]))
|
|| EXTRA_ADDRESS_CONSTRAINT (constraints[i][0], constraints[i]))
|
||||||
record_address_regs (recog_data.operand[i],
|
record_address_regs (VOIDmode, recog_data.operand[i], 0, ADDRESS,
|
||||||
MODE_BASE_REG_CLASS (modes[i]), frequency * 2);
|
SCRATCH, frequency * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for commutative in a separate loop so everything will
|
/* Check for commutative in a separate loop so everything will
|
||||||
@ -1037,8 +1063,8 @@ scan_one_insn (rtx insn, int pass)
|
|||||||
-= (MEMORY_MOVE_COST (GET_MODE (SET_DEST (set)),
|
-= (MEMORY_MOVE_COST (GET_MODE (SET_DEST (set)),
|
||||||
GENERAL_REGS, 1)
|
GENERAL_REGS, 1)
|
||||||
* frequency);
|
* frequency);
|
||||||
record_address_regs (XEXP (SET_SRC (set), 0),
|
record_address_regs (GET_MODE (SET_SRC (set)), XEXP (SET_SRC (set), 0),
|
||||||
MODE_BASE_REG_CLASS (VOIDmode), frequency * 2);
|
0, MEM, SCRATCH, frequency * 2);
|
||||||
return insn;
|
return insn;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1148,7 +1174,12 @@ init_reg_autoinc (void)
|
|||||||
m = (enum machine_mode) ((int) m + 1))
|
m = (enum machine_mode) ((int) m + 1))
|
||||||
if (HARD_REGNO_MODE_OK (j, m))
|
if (HARD_REGNO_MODE_OK (j, m))
|
||||||
{
|
{
|
||||||
enum reg_class base_class = MODE_BASE_REG_CLASS (VOIDmode);
|
/* ??? There are two assumptions here; that the base class does not
|
||||||
|
depend on the exact outer code (POST_INC vs. PRE_INC etc.), and
|
||||||
|
that it does not depend on the machine mode of the memory
|
||||||
|
reference. */
|
||||||
|
enum reg_class base_class
|
||||||
|
= base_reg_class (VOIDmode, POST_INC, SCRATCH);
|
||||||
|
|
||||||
PUT_MODE (r, m);
|
PUT_MODE (r, m);
|
||||||
|
|
||||||
@ -1544,7 +1575,7 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops,
|
|||||||
address, i.e. BASE_REG_CLASS. */
|
address, i.e. BASE_REG_CLASS. */
|
||||||
classes[i]
|
classes[i]
|
||||||
= reg_class_subunion[(int) classes[i]]
|
= reg_class_subunion[(int) classes[i]]
|
||||||
[(int) MODE_BASE_REG_CLASS (VOIDmode)];
|
[(int) base_reg_class (VOIDmode, ADDRESS, SCRATCH)];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'm': case 'o': case 'V':
|
case 'm': case 'o': case 'V':
|
||||||
@ -1658,7 +1689,7 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops,
|
|||||||
address, i.e. BASE_REG_CLASS. */
|
address, i.e. BASE_REG_CLASS. */
|
||||||
classes[i]
|
classes[i]
|
||||||
= reg_class_subunion[(int) classes[i]]
|
= reg_class_subunion[(int) classes[i]]
|
||||||
[(int) MODE_BASE_REG_CLASS (VOIDmode)];
|
[(int) base_reg_class (VOIDmode, ADDRESS, SCRATCH)];
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
@ -1890,16 +1921,28 @@ copy_cost (rtx x, enum machine_mode mode, enum reg_class class, int to_p,
|
|||||||
/* Record the pseudo registers we must reload into hard registers
|
/* Record the pseudo registers we must reload into hard registers
|
||||||
in a subexpression of a memory address, X.
|
in a subexpression of a memory address, X.
|
||||||
|
|
||||||
CLASS is the class that the register needs to be in and is either
|
If CONTEXT is 0, we are looking at the base part of an address, otherwise we
|
||||||
BASE_REG_CLASS or INDEX_REG_CLASS.
|
are looking at the index part.
|
||||||
|
|
||||||
|
MODE is the mode of the memory reference; OUTER_CODE and INDEX_CODE
|
||||||
|
give the context that the rtx appears in. These three arguments are
|
||||||
|
passed down to base_reg_class.
|
||||||
|
|
||||||
SCALE is twice the amount to multiply the cost by (it is twice so we
|
SCALE is twice the amount to multiply the cost by (it is twice so we
|
||||||
can represent half-cost adjustments). */
|
can represent half-cost adjustments). */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
record_address_regs (rtx x, enum reg_class class, int scale)
|
record_address_regs (enum machine_mode mode, rtx x, int context,
|
||||||
|
enum rtx_code outer_code, enum rtx_code index_code,
|
||||||
|
int scale)
|
||||||
{
|
{
|
||||||
enum rtx_code code = GET_CODE (x);
|
enum rtx_code code = GET_CODE (x);
|
||||||
|
enum reg_class class;
|
||||||
|
|
||||||
|
if (context == 1)
|
||||||
|
class = INDEX_REG_CLASS;
|
||||||
|
else
|
||||||
|
class = base_reg_class (mode, outer_code, index_code);
|
||||||
|
|
||||||
switch (code)
|
switch (code)
|
||||||
{
|
{
|
||||||
@ -1940,31 +1983,31 @@ record_address_regs (rtx x, enum reg_class class, int scale)
|
|||||||
be in the first operand. */
|
be in the first operand. */
|
||||||
|
|
||||||
if (MAX_REGS_PER_ADDRESS == 1)
|
if (MAX_REGS_PER_ADDRESS == 1)
|
||||||
record_address_regs (arg0, class, scale);
|
record_address_regs (mode, arg0, 0, PLUS, code1, scale);
|
||||||
|
|
||||||
/* If index and base registers are the same on this machine, just
|
/* If index and base registers are the same on this machine, just
|
||||||
record registers in any non-constant operands. We assume here,
|
record registers in any non-constant operands. We assume here,
|
||||||
as well as in the tests below, that all addresses are in
|
as well as in the tests below, that all addresses are in
|
||||||
canonical form. */
|
canonical form. */
|
||||||
|
|
||||||
else if (INDEX_REG_CLASS == MODE_BASE_REG_CLASS (VOIDmode))
|
else if (INDEX_REG_CLASS == base_reg_class (VOIDmode, PLUS, SCRATCH))
|
||||||
{
|
{
|
||||||
record_address_regs (arg0, class, scale);
|
record_address_regs (mode, arg0, context, PLUS, code1, scale);
|
||||||
if (! CONSTANT_P (arg1))
|
if (! CONSTANT_P (arg1))
|
||||||
record_address_regs (arg1, class, scale);
|
record_address_regs (mode, arg1, context, PLUS, code0, scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the second operand is a constant integer, it doesn't change
|
/* If the second operand is a constant integer, it doesn't change
|
||||||
what class the first operand must be. */
|
what class the first operand must be. */
|
||||||
|
|
||||||
else if (code1 == CONST_INT || code1 == CONST_DOUBLE)
|
else if (code1 == CONST_INT || code1 == CONST_DOUBLE)
|
||||||
record_address_regs (arg0, class, scale);
|
record_address_regs (mode, arg0, context, PLUS, code1, scale);
|
||||||
|
|
||||||
/* If the second operand is a symbolic constant, the first operand
|
/* If the second operand is a symbolic constant, the first operand
|
||||||
must be an index register. */
|
must be an index register. */
|
||||||
|
|
||||||
else if (code1 == SYMBOL_REF || code1 == CONST || code1 == LABEL_REF)
|
else if (code1 == SYMBOL_REF || code1 == CONST || code1 == LABEL_REF)
|
||||||
record_address_regs (arg0, INDEX_REG_CLASS, scale);
|
record_address_regs (mode, arg0, 1, PLUS, code1, scale);
|
||||||
|
|
||||||
/* If both operands are registers but one is already a hard register
|
/* If both operands are registers but one is already a hard register
|
||||||
of index or reg-base class, give the other the class that the
|
of index or reg-base class, give the other the class that the
|
||||||
@ -1972,22 +2015,20 @@ record_address_regs (rtx x, enum reg_class class, int scale)
|
|||||||
|
|
||||||
else if (code0 == REG && code1 == REG
|
else if (code0 == REG && code1 == REG
|
||||||
&& REGNO (arg0) < FIRST_PSEUDO_REGISTER
|
&& REGNO (arg0) < FIRST_PSEUDO_REGISTER
|
||||||
&& (REG_MODE_OK_FOR_REG_BASE_P (arg0, VOIDmode)
|
&& (ok_for_base_p_nonstrict (arg0, mode, PLUS, REG)
|
||||||
|| REG_OK_FOR_INDEX_P (arg0)))
|
|| ok_for_index_p_nonstrict (arg0)))
|
||||||
record_address_regs (arg1,
|
record_address_regs (mode, arg1,
|
||||||
REG_MODE_OK_FOR_REG_BASE_P (arg0, VOIDmode)
|
ok_for_base_p_nonstrict (arg0, mode, PLUS, REG)
|
||||||
? INDEX_REG_CLASS
|
? 1 : 0,
|
||||||
: MODE_BASE_REG_REG_CLASS (VOIDmode),
|
PLUS, REG, scale);
|
||||||
scale);
|
|
||||||
else if (code0 == REG && code1 == REG
|
else if (code0 == REG && code1 == REG
|
||||||
&& REGNO (arg1) < FIRST_PSEUDO_REGISTER
|
&& REGNO (arg1) < FIRST_PSEUDO_REGISTER
|
||||||
&& (REG_MODE_OK_FOR_REG_BASE_P (arg1, VOIDmode)
|
&& (ok_for_base_p_nonstrict (arg1, mode, PLUS, REG)
|
||||||
|| REG_OK_FOR_INDEX_P (arg1)))
|
|| ok_for_index_p_nonstrict (arg1)))
|
||||||
record_address_regs (arg0,
|
record_address_regs (mode, arg0,
|
||||||
REG_MODE_OK_FOR_REG_BASE_P (arg1, VOIDmode)
|
ok_for_base_p_nonstrict (arg1, mode, PLUS, REG)
|
||||||
? INDEX_REG_CLASS
|
? 1 : 0,
|
||||||
: MODE_BASE_REG_REG_CLASS (VOIDmode),
|
PLUS, REG, scale);
|
||||||
scale);
|
|
||||||
|
|
||||||
/* If one operand is known to be a pointer, it must be the base
|
/* If one operand is known to be a pointer, it must be the base
|
||||||
with the other operand the index. Likewise if the other operand
|
with the other operand the index. Likewise if the other operand
|
||||||
@ -1996,16 +2037,14 @@ record_address_regs (rtx x, enum reg_class class, int scale)
|
|||||||
else if ((code0 == REG && REG_POINTER (arg0))
|
else if ((code0 == REG && REG_POINTER (arg0))
|
||||||
|| code1 == MULT)
|
|| code1 == MULT)
|
||||||
{
|
{
|
||||||
record_address_regs (arg0, MODE_BASE_REG_REG_CLASS (VOIDmode),
|
record_address_regs (mode, arg0, 0, PLUS, code1, scale);
|
||||||
scale);
|
record_address_regs (mode, arg1, 1, PLUS, code0, scale);
|
||||||
record_address_regs (arg1, INDEX_REG_CLASS, scale);
|
|
||||||
}
|
}
|
||||||
else if ((code1 == REG && REG_POINTER (arg1))
|
else if ((code1 == REG && REG_POINTER (arg1))
|
||||||
|| code0 == MULT)
|
|| code0 == MULT)
|
||||||
{
|
{
|
||||||
record_address_regs (arg0, INDEX_REG_CLASS, scale);
|
record_address_regs (mode, arg0, 1, PLUS, code1, scale);
|
||||||
record_address_regs (arg1, MODE_BASE_REG_REG_CLASS (VOIDmode),
|
record_address_regs (mode, arg1, 0, PLUS, code0, scale);
|
||||||
scale);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Otherwise, count equal chances that each might be a base
|
/* Otherwise, count equal chances that each might be a base
|
||||||
@ -2013,12 +2052,10 @@ record_address_regs (rtx x, enum reg_class class, int scale)
|
|||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
record_address_regs (arg0, MODE_BASE_REG_REG_CLASS (VOIDmode),
|
record_address_regs (mode, arg0, 0, PLUS, code1, scale / 2);
|
||||||
scale / 2);
|
record_address_regs (mode, arg0, 1, PLUS, code1, scale / 2);
|
||||||
record_address_regs (arg0, INDEX_REG_CLASS, scale / 2);
|
record_address_regs (mode, arg1, 0, PLUS, code0, scale / 2);
|
||||||
record_address_regs (arg1, MODE_BASE_REG_REG_CLASS (VOIDmode),
|
record_address_regs (mode, arg1, 1, PLUS, code0, scale / 2);
|
||||||
scale / 2);
|
|
||||||
record_address_regs (arg1, INDEX_REG_CLASS, scale / 2);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -2028,11 +2065,11 @@ record_address_regs (rtx x, enum reg_class class, int scale)
|
|||||||
if it ends up in the wrong place. */
|
if it ends up in the wrong place. */
|
||||||
case POST_MODIFY:
|
case POST_MODIFY:
|
||||||
case PRE_MODIFY:
|
case PRE_MODIFY:
|
||||||
record_address_regs (XEXP (x, 0), MODE_BASE_REG_CLASS (VOIDmode),
|
record_address_regs (mode, XEXP (x, 0), 0, code,
|
||||||
2 * scale);
|
GET_CODE (XEXP (XEXP (x, 1), 1)), 2 * scale);
|
||||||
if (REG_P (XEXP (XEXP (x, 1), 1)))
|
if (REG_P (XEXP (XEXP (x, 1), 1)))
|
||||||
record_address_regs (XEXP (XEXP (x, 1), 1),
|
record_address_regs (mode, XEXP (XEXP (x, 1), 1), 1, code, REG,
|
||||||
INDEX_REG_CLASS, 2 * scale);
|
2 * scale);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case POST_INC:
|
case POST_INC:
|
||||||
@ -2050,7 +2087,7 @@ record_address_regs (rtx x, enum reg_class class, int scale)
|
|||||||
in_inc_dec[REGNO (XEXP (x, 0))] = 1;
|
in_inc_dec[REGNO (XEXP (x, 0))] = 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
record_address_regs (XEXP (x, 0), class, 2 * scale);
|
record_address_regs (mode, XEXP (x, 0), 0, code, SCRATCH, 2 * scale);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case REG:
|
case REG:
|
||||||
@ -2071,7 +2108,8 @@ record_address_regs (rtx x, enum reg_class class, int scale)
|
|||||||
int i;
|
int i;
|
||||||
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
|
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
|
||||||
if (fmt[i] == 'e')
|
if (fmt[i] == 'e')
|
||||||
record_address_regs (XEXP (x, i), class, scale);
|
record_address_regs (mode, XEXP (x, i), context, code, SCRATCH,
|
||||||
|
scale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "tm_p.h"
|
#include "tm_p.h"
|
||||||
#include "insn-config.h"
|
#include "insn-config.h"
|
||||||
#include "regs.h"
|
#include "regs.h"
|
||||||
|
#include "addresses.h"
|
||||||
#include "hard-reg-set.h"
|
#include "hard-reg-set.h"
|
||||||
#include "basic-block.h"
|
#include "basic-block.h"
|
||||||
#include "reload.h"
|
#include "reload.h"
|
||||||
@ -528,7 +529,7 @@ scan_rtx_address (rtx insn, rtx *loc, enum reg_class cl,
|
|||||||
rtx op1 = orig_op1;
|
rtx op1 = orig_op1;
|
||||||
rtx *locI = NULL;
|
rtx *locI = NULL;
|
||||||
rtx *locB = NULL;
|
rtx *locB = NULL;
|
||||||
rtx *locB_reg = NULL;
|
enum rtx_code index_code;
|
||||||
|
|
||||||
if (GET_CODE (op0) == SUBREG)
|
if (GET_CODE (op0) == SUBREG)
|
||||||
{
|
{
|
||||||
@ -547,59 +548,70 @@ scan_rtx_address (rtx insn, rtx *loc, enum reg_class cl,
|
|||||||
{
|
{
|
||||||
locI = &XEXP (x, 0);
|
locI = &XEXP (x, 0);
|
||||||
locB = &XEXP (x, 1);
|
locB = &XEXP (x, 1);
|
||||||
|
index_code = GET_CODE (*locI);
|
||||||
}
|
}
|
||||||
else if (code1 == MULT || code1 == SIGN_EXTEND || code1 == TRUNCATE
|
else if (code1 == MULT || code1 == SIGN_EXTEND || code1 == TRUNCATE
|
||||||
|| code1 == ZERO_EXTEND || code0 == MEM)
|
|| code1 == ZERO_EXTEND || code0 == MEM)
|
||||||
{
|
{
|
||||||
locI = &XEXP (x, 1);
|
locI = &XEXP (x, 1);
|
||||||
locB = &XEXP (x, 0);
|
locB = &XEXP (x, 0);
|
||||||
|
index_code = GET_CODE (*locI);
|
||||||
}
|
}
|
||||||
else if (code0 == CONST_INT || code0 == CONST
|
else if (code0 == CONST_INT || code0 == CONST
|
||||||
|| code0 == SYMBOL_REF || code0 == LABEL_REF)
|
|| code0 == SYMBOL_REF || code0 == LABEL_REF)
|
||||||
locB = &XEXP (x, 1);
|
{
|
||||||
|
locB = &XEXP (x, 1);
|
||||||
|
index_code = GET_CODE (XEXP (x, 0));
|
||||||
|
}
|
||||||
else if (code1 == CONST_INT || code1 == CONST
|
else if (code1 == CONST_INT || code1 == CONST
|
||||||
|| code1 == SYMBOL_REF || code1 == LABEL_REF)
|
|| code1 == SYMBOL_REF || code1 == LABEL_REF)
|
||||||
locB = &XEXP (x, 0);
|
{
|
||||||
|
locB = &XEXP (x, 0);
|
||||||
|
index_code = GET_CODE (XEXP (x, 1));
|
||||||
|
}
|
||||||
else if (code0 == REG && code1 == REG)
|
else if (code0 == REG && code1 == REG)
|
||||||
{
|
{
|
||||||
int index_op;
|
int index_op;
|
||||||
|
unsigned regno0 = REGNO (op0), regno1 = REGNO (op1);
|
||||||
|
|
||||||
if (REG_OK_FOR_INDEX_P (op0)
|
if (REGNO_OK_FOR_INDEX_P (regno0)
|
||||||
&& REG_MODE_OK_FOR_REG_BASE_P (op1, mode))
|
&& regno_ok_for_base_p (regno1, mode, PLUS, REG))
|
||||||
index_op = 0;
|
index_op = 0;
|
||||||
else if (REG_OK_FOR_INDEX_P (op1)
|
else if (REGNO_OK_FOR_INDEX_P (regno1)
|
||||||
&& REG_MODE_OK_FOR_REG_BASE_P (op0, mode))
|
&& regno_ok_for_base_p (regno0, mode, PLUS, REG))
|
||||||
index_op = 1;
|
index_op = 1;
|
||||||
else if (REG_MODE_OK_FOR_REG_BASE_P (op1, mode))
|
else if (regno_ok_for_base_p (regno1, mode, PLUS, REG))
|
||||||
index_op = 0;
|
index_op = 0;
|
||||||
else if (REG_MODE_OK_FOR_REG_BASE_P (op0, mode))
|
else if (regno_ok_for_base_p (regno0, mode, PLUS, REG))
|
||||||
index_op = 1;
|
index_op = 1;
|
||||||
else if (REG_OK_FOR_INDEX_P (op1))
|
else if (REGNO_OK_FOR_INDEX_P (regno1))
|
||||||
index_op = 1;
|
index_op = 1;
|
||||||
else
|
else
|
||||||
index_op = 0;
|
index_op = 0;
|
||||||
|
|
||||||
locI = &XEXP (x, index_op);
|
locI = &XEXP (x, index_op);
|
||||||
locB_reg = &XEXP (x, !index_op);
|
locB = &XEXP (x, !index_op);
|
||||||
|
index_code = GET_CODE (*locI);
|
||||||
}
|
}
|
||||||
else if (code0 == REG)
|
else if (code0 == REG)
|
||||||
{
|
{
|
||||||
locI = &XEXP (x, 0);
|
locI = &XEXP (x, 0);
|
||||||
locB = &XEXP (x, 1);
|
locB = &XEXP (x, 1);
|
||||||
|
index_code = GET_CODE (*locI);
|
||||||
}
|
}
|
||||||
else if (code1 == REG)
|
else if (code1 == REG)
|
||||||
{
|
{
|
||||||
locI = &XEXP (x, 1);
|
locI = &XEXP (x, 1);
|
||||||
locB = &XEXP (x, 0);
|
locB = &XEXP (x, 0);
|
||||||
|
index_code = GET_CODE (*locI);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (locI)
|
if (locI)
|
||||||
scan_rtx_address (insn, locI, INDEX_REG_CLASS, action, mode);
|
scan_rtx_address (insn, locI, INDEX_REG_CLASS, action, mode);
|
||||||
if (locB)
|
if (locB)
|
||||||
scan_rtx_address (insn, locB, MODE_BASE_REG_CLASS (mode), action, mode);
|
scan_rtx_address (insn, locB, base_reg_class (mode, PLUS, index_code),
|
||||||
if (locB_reg)
|
|
||||||
scan_rtx_address (insn, locB_reg, MODE_BASE_REG_REG_CLASS (mode),
|
|
||||||
action, mode);
|
action, mode);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -618,7 +630,7 @@ scan_rtx_address (rtx insn, rtx *loc, enum reg_class cl,
|
|||||||
|
|
||||||
case MEM:
|
case MEM:
|
||||||
scan_rtx_address (insn, &XEXP (x, 0),
|
scan_rtx_address (insn, &XEXP (x, 0),
|
||||||
MODE_BASE_REG_CLASS (GET_MODE (x)), action,
|
base_reg_class (GET_MODE (x), MEM, SCRATCH), action,
|
||||||
GET_MODE (x));
|
GET_MODE (x));
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -669,7 +681,7 @@ scan_rtx (rtx insn, rtx *loc, enum reg_class cl,
|
|||||||
|
|
||||||
case MEM:
|
case MEM:
|
||||||
scan_rtx_address (insn, &XEXP (x, 0),
|
scan_rtx_address (insn, &XEXP (x, 0),
|
||||||
MODE_BASE_REG_CLASS (GET_MODE (x)), action,
|
base_reg_class (GET_MODE (x), MEM, SCRATCH), action,
|
||||||
GET_MODE (x));
|
GET_MODE (x));
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -1441,7 +1453,7 @@ replace_oldest_value_addr (rtx *loc, enum reg_class cl,
|
|||||||
rtx op1 = orig_op1;
|
rtx op1 = orig_op1;
|
||||||
rtx *locI = NULL;
|
rtx *locI = NULL;
|
||||||
rtx *locB = NULL;
|
rtx *locB = NULL;
|
||||||
rtx *locB_reg = NULL;
|
enum rtx_code index_code;
|
||||||
|
|
||||||
if (GET_CODE (op0) == SUBREG)
|
if (GET_CODE (op0) == SUBREG)
|
||||||
{
|
{
|
||||||
@ -1460,50 +1472,62 @@ replace_oldest_value_addr (rtx *loc, enum reg_class cl,
|
|||||||
{
|
{
|
||||||
locI = &XEXP (x, 0);
|
locI = &XEXP (x, 0);
|
||||||
locB = &XEXP (x, 1);
|
locB = &XEXP (x, 1);
|
||||||
|
index_code = GET_CODE (*locI);
|
||||||
}
|
}
|
||||||
else if (code1 == MULT || code1 == SIGN_EXTEND || code1 == TRUNCATE
|
else if (code1 == MULT || code1 == SIGN_EXTEND || code1 == TRUNCATE
|
||||||
|| code1 == ZERO_EXTEND || code0 == MEM)
|
|| code1 == ZERO_EXTEND || code0 == MEM)
|
||||||
{
|
{
|
||||||
locI = &XEXP (x, 1);
|
locI = &XEXP (x, 1);
|
||||||
locB = &XEXP (x, 0);
|
locB = &XEXP (x, 0);
|
||||||
|
index_code = GET_CODE (*locI);
|
||||||
}
|
}
|
||||||
else if (code0 == CONST_INT || code0 == CONST
|
else if (code0 == CONST_INT || code0 == CONST
|
||||||
|| code0 == SYMBOL_REF || code0 == LABEL_REF)
|
|| code0 == SYMBOL_REF || code0 == LABEL_REF)
|
||||||
locB = &XEXP (x, 1);
|
{
|
||||||
|
locB = &XEXP (x, 1);
|
||||||
|
index_code = GET_CODE (XEXP (x, 0));
|
||||||
|
}
|
||||||
else if (code1 == CONST_INT || code1 == CONST
|
else if (code1 == CONST_INT || code1 == CONST
|
||||||
|| code1 == SYMBOL_REF || code1 == LABEL_REF)
|
|| code1 == SYMBOL_REF || code1 == LABEL_REF)
|
||||||
locB = &XEXP (x, 0);
|
{
|
||||||
|
locB = &XEXP (x, 0);
|
||||||
|
index_code = GET_CODE (XEXP (x, 1));
|
||||||
|
}
|
||||||
else if (code0 == REG && code1 == REG)
|
else if (code0 == REG && code1 == REG)
|
||||||
{
|
{
|
||||||
int index_op;
|
int index_op;
|
||||||
|
unsigned regno0 = REGNO (op0), regno1 = REGNO (op1);
|
||||||
|
|
||||||
if (REG_OK_FOR_INDEX_P (op0)
|
if (REGNO_OK_FOR_INDEX_P (regno0)
|
||||||
&& REG_MODE_OK_FOR_REG_BASE_P (op1, mode))
|
&& regno_ok_for_base_p (regno1, mode, PLUS, REG))
|
||||||
index_op = 0;
|
index_op = 0;
|
||||||
else if (REG_OK_FOR_INDEX_P (op1)
|
else if (REGNO_OK_FOR_INDEX_P (regno1)
|
||||||
&& REG_MODE_OK_FOR_REG_BASE_P (op0, mode))
|
&& regno_ok_for_base_p (regno0, mode, PLUS, REG))
|
||||||
index_op = 1;
|
index_op = 1;
|
||||||
else if (REG_MODE_OK_FOR_REG_BASE_P (op1, mode))
|
else if (regno_ok_for_base_p (regno1, mode, PLUS, REG))
|
||||||
index_op = 0;
|
index_op = 0;
|
||||||
else if (REG_MODE_OK_FOR_REG_BASE_P (op0, mode))
|
else if (regno_ok_for_base_p (regno0, mode, PLUS, REG))
|
||||||
index_op = 1;
|
index_op = 1;
|
||||||
else if (REG_OK_FOR_INDEX_P (op1))
|
else if (REGNO_OK_FOR_INDEX_P (regno1))
|
||||||
index_op = 1;
|
index_op = 1;
|
||||||
else
|
else
|
||||||
index_op = 0;
|
index_op = 0;
|
||||||
|
|
||||||
locI = &XEXP (x, index_op);
|
locI = &XEXP (x, index_op);
|
||||||
locB_reg = &XEXP (x, !index_op);
|
locB = &XEXP (x, !index_op);
|
||||||
|
index_code = GET_CODE (*locI);
|
||||||
}
|
}
|
||||||
else if (code0 == REG)
|
else if (code0 == REG)
|
||||||
{
|
{
|
||||||
locI = &XEXP (x, 0);
|
locI = &XEXP (x, 0);
|
||||||
locB = &XEXP (x, 1);
|
locB = &XEXP (x, 1);
|
||||||
|
index_code = GET_CODE (*locI);
|
||||||
}
|
}
|
||||||
else if (code1 == REG)
|
else if (code1 == REG)
|
||||||
{
|
{
|
||||||
locI = &XEXP (x, 1);
|
locI = &XEXP (x, 1);
|
||||||
locB = &XEXP (x, 0);
|
locB = &XEXP (x, 0);
|
||||||
|
index_code = GET_CODE (*locI);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (locI)
|
if (locI)
|
||||||
@ -1511,11 +1535,8 @@ replace_oldest_value_addr (rtx *loc, enum reg_class cl,
|
|||||||
insn, vd);
|
insn, vd);
|
||||||
if (locB)
|
if (locB)
|
||||||
changed |= replace_oldest_value_addr (locB,
|
changed |= replace_oldest_value_addr (locB,
|
||||||
MODE_BASE_REG_CLASS (mode),
|
base_reg_class (mode, PLUS,
|
||||||
mode, insn, vd);
|
index_code),
|
||||||
if (locB_reg)
|
|
||||||
changed |= replace_oldest_value_addr (locB_reg,
|
|
||||||
MODE_BASE_REG_REG_CLASS (mode),
|
|
||||||
mode, insn, vd);
|
mode, insn, vd);
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
@ -1559,7 +1580,8 @@ static bool
|
|||||||
replace_oldest_value_mem (rtx x, rtx insn, struct value_data *vd)
|
replace_oldest_value_mem (rtx x, rtx insn, struct value_data *vd)
|
||||||
{
|
{
|
||||||
return replace_oldest_value_addr (&XEXP (x, 0),
|
return replace_oldest_value_addr (&XEXP (x, 0),
|
||||||
MODE_BASE_REG_CLASS (GET_MODE (x)),
|
base_reg_class (GET_MODE (x), MEM,
|
||||||
|
SCRATCH),
|
||||||
GET_MODE (x), insn, vd);
|
GET_MODE (x), insn, vd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
229
gcc/reload.c
229
gcc/reload.c
@ -100,6 +100,7 @@ a register with any other reload. */
|
|||||||
#include "recog.h"
|
#include "recog.h"
|
||||||
#include "reload.h"
|
#include "reload.h"
|
||||||
#include "regs.h"
|
#include "regs.h"
|
||||||
|
#include "addresses.h"
|
||||||
#include "hard-reg-set.h"
|
#include "hard-reg-set.h"
|
||||||
#include "flags.h"
|
#include "flags.h"
|
||||||
#include "real.h"
|
#include "real.h"
|
||||||
@ -269,7 +270,8 @@ static int find_reloads_address (enum machine_mode, rtx *, rtx, rtx *,
|
|||||||
static rtx subst_reg_equivs (rtx, rtx);
|
static rtx subst_reg_equivs (rtx, rtx);
|
||||||
static rtx subst_indexed_address (rtx);
|
static rtx subst_indexed_address (rtx);
|
||||||
static void update_auto_inc_notes (rtx, int, int);
|
static void update_auto_inc_notes (rtx, int, int);
|
||||||
static int find_reloads_address_1 (enum machine_mode, rtx, int, rtx *,
|
static int find_reloads_address_1 (enum machine_mode, rtx, int,
|
||||||
|
enum rtx_code, enum rtx_code, rtx *,
|
||||||
int, enum reload_type,int, rtx);
|
int, enum reload_type,int, rtx);
|
||||||
static void find_reloads_address_part (rtx, rtx *, enum reg_class,
|
static void find_reloads_address_part (rtx, rtx *, enum reg_class,
|
||||||
enum machine_mode, int,
|
enum machine_mode, int,
|
||||||
@ -3119,7 +3121,8 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
|
|||||||
case 'p':
|
case 'p':
|
||||||
/* All necessary reloads for an address_operand
|
/* All necessary reloads for an address_operand
|
||||||
were handled in find_reloads_address. */
|
were handled in find_reloads_address. */
|
||||||
this_alternative[i] = (int) MODE_BASE_REG_CLASS (VOIDmode);
|
this_alternative[i]
|
||||||
|
= (int) base_reg_class (VOIDmode, ADDRESS, SCRATCH);
|
||||||
win = 1;
|
win = 1;
|
||||||
badop = 0;
|
badop = 0;
|
||||||
break;
|
break;
|
||||||
@ -3323,7 +3326,8 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
|
|||||||
|
|
||||||
/* If we didn't already win, we can reload
|
/* If we didn't already win, we can reload
|
||||||
the address into a base register. */
|
the address into a base register. */
|
||||||
this_alternative[i] = (int) MODE_BASE_REG_CLASS (VOIDmode);
|
this_alternative[i]
|
||||||
|
= (int) base_reg_class (VOIDmode, ADDRESS, SCRATCH);
|
||||||
badop = 0;
|
badop = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -3826,7 +3830,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
|
|||||||
operand_reloadnum[i]
|
operand_reloadnum[i]
|
||||||
= push_reload (XEXP (recog_data.operand[i], 0), NULL_RTX,
|
= push_reload (XEXP (recog_data.operand[i], 0), NULL_RTX,
|
||||||
&XEXP (recog_data.operand[i], 0), (rtx*) 0,
|
&XEXP (recog_data.operand[i], 0), (rtx*) 0,
|
||||||
MODE_BASE_REG_CLASS (VOIDmode),
|
base_reg_class (VOIDmode, MEM, SCRATCH),
|
||||||
GET_MODE (XEXP (recog_data.operand[i], 0)),
|
GET_MODE (XEXP (recog_data.operand[i], 0)),
|
||||||
VOIDmode, 0, 0, i, RELOAD_FOR_INPUT);
|
VOIDmode, 0, 0, i, RELOAD_FOR_INPUT);
|
||||||
rld[operand_reloadnum[i]].inc
|
rld[operand_reloadnum[i]].inc
|
||||||
@ -4745,12 +4749,12 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
|
|||||||
subject of a CLOBBER in this insn. */
|
subject of a CLOBBER in this insn. */
|
||||||
|
|
||||||
else if (regno < FIRST_PSEUDO_REGISTER
|
else if (regno < FIRST_PSEUDO_REGISTER
|
||||||
&& REGNO_MODE_OK_FOR_BASE_P (regno, mode)
|
&& regno_ok_for_base_p (regno, mode, MEM, SCRATCH)
|
||||||
&& ! regno_clobbered_p (regno, this_insn, mode, 0))
|
&& ! regno_clobbered_p (regno, this_insn, mode, 0))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* If we do not have one of the cases above, we must do the reload. */
|
/* If we do not have one of the cases above, we must do the reload. */
|
||||||
push_reload (ad, NULL_RTX, loc, (rtx*) 0, MODE_BASE_REG_CLASS (mode),
|
push_reload (ad, NULL_RTX, loc, (rtx*) 0, base_reg_class (mode, MEM, SCRATCH),
|
||||||
GET_MODE (ad), VOIDmode, 0, 0, opnum, type);
|
GET_MODE (ad), VOIDmode, 0, 0, opnum, type);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -4851,7 +4855,7 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
|
|||||||
/* Must use TEM here, not AD, since it is the one that will
|
/* Must use TEM here, not AD, since it is the one that will
|
||||||
have any subexpressions reloaded, if needed. */
|
have any subexpressions reloaded, if needed. */
|
||||||
push_reload (tem, NULL_RTX, loc, (rtx*) 0,
|
push_reload (tem, NULL_RTX, loc, (rtx*) 0,
|
||||||
MODE_BASE_REG_CLASS (mode), GET_MODE (tem),
|
base_reg_class (mode, MEM, SCRATCH), GET_MODE (tem),
|
||||||
VOIDmode, 0,
|
VOIDmode, 0,
|
||||||
0, opnum, type);
|
0, opnum, type);
|
||||||
return ! removed_and;
|
return ! removed_and;
|
||||||
@ -4868,8 +4872,10 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
|
|||||||
else if (GET_CODE (ad) == PLUS
|
else if (GET_CODE (ad) == PLUS
|
||||||
&& REG_P (XEXP (ad, 0))
|
&& REG_P (XEXP (ad, 0))
|
||||||
&& REGNO (XEXP (ad, 0)) < FIRST_PSEUDO_REGISTER
|
&& REGNO (XEXP (ad, 0)) < FIRST_PSEUDO_REGISTER
|
||||||
&& REG_MODE_OK_FOR_BASE_P (XEXP (ad, 0), mode)
|
&& GET_CODE (XEXP (ad, 1)) == CONST_INT
|
||||||
&& GET_CODE (XEXP (ad, 1)) == CONST_INT)
|
&& regno_ok_for_base_p (REGNO (XEXP (ad, 0)), mode, PLUS,
|
||||||
|
CONST_INT))
|
||||||
|
|
||||||
{
|
{
|
||||||
/* Unshare the MEM rtx so we can safely alter it. */
|
/* Unshare the MEM rtx so we can safely alter it. */
|
||||||
if (memrefloc)
|
if (memrefloc)
|
||||||
@ -4897,7 +4903,8 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
|
|||||||
/* If the sum of two regs is not necessarily valid,
|
/* If the sum of two regs is not necessarily valid,
|
||||||
reload the sum into a base reg.
|
reload the sum into a base reg.
|
||||||
That will at least work. */
|
That will at least work. */
|
||||||
find_reloads_address_part (ad, loc, MODE_BASE_REG_CLASS (mode),
|
find_reloads_address_part (ad, loc,
|
||||||
|
base_reg_class (mode, MEM, SCRATCH),
|
||||||
Pmode, opnum, type, ind_levels);
|
Pmode, opnum, type, ind_levels);
|
||||||
}
|
}
|
||||||
return ! removed_and;
|
return ! removed_and;
|
||||||
@ -4931,19 +4938,26 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
|
|||||||
|
|
||||||
for (op_index = 0; op_index < 2; ++op_index)
|
for (op_index = 0; op_index < 2; ++op_index)
|
||||||
{
|
{
|
||||||
rtx operand;
|
rtx operand, addend;
|
||||||
|
enum rtx_code inner_code;
|
||||||
|
|
||||||
|
if (GET_CODE (ad) != PLUS)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
inner_code = GET_CODE (XEXP (ad, 0));
|
||||||
if (!(GET_CODE (ad) == PLUS
|
if (!(GET_CODE (ad) == PLUS
|
||||||
&& GET_CODE (XEXP (ad, 1)) == CONST_INT
|
&& GET_CODE (XEXP (ad, 1)) == CONST_INT
|
||||||
&& (GET_CODE (XEXP (ad, 0)) == PLUS
|
&& (inner_code == PLUS || inner_code == LO_SUM)))
|
||||||
|| GET_CODE (XEXP (ad, 0)) == LO_SUM)))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
operand = XEXP (XEXP (ad, 0), op_index);
|
operand = XEXP (XEXP (ad, 0), op_index);
|
||||||
if (!REG_P (operand) || REGNO (operand) >= FIRST_PSEUDO_REGISTER)
|
if (!REG_P (operand) || REGNO (operand) >= FIRST_PSEUDO_REGISTER)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((REG_MODE_OK_FOR_BASE_P (operand, mode)
|
addend = XEXP (XEXP (ad, 0), 1 - op_index);
|
||||||
|
|
||||||
|
if ((regno_ok_for_base_p (REGNO (operand), mode, inner_code,
|
||||||
|
GET_CODE (addend))
|
||||||
|| operand == frame_pointer_rtx
|
|| operand == frame_pointer_rtx
|
||||||
#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
|
#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
|
||||||
|| operand == hard_frame_pointer_rtx
|
|| operand == hard_frame_pointer_rtx
|
||||||
@ -4956,11 +4970,10 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
|
|||||||
&XEXP (XEXP (ad, 0), 1 - op_index)))
|
&XEXP (XEXP (ad, 0), 1 - op_index)))
|
||||||
{
|
{
|
||||||
rtx offset_reg;
|
rtx offset_reg;
|
||||||
rtx addend;
|
enum reg_class cls;
|
||||||
|
|
||||||
offset_reg = plus_constant (operand, INTVAL (XEXP (ad, 1)));
|
offset_reg = plus_constant (operand, INTVAL (XEXP (ad, 1)));
|
||||||
addend = XEXP (XEXP (ad, 0), 1 - op_index);
|
|
||||||
|
|
||||||
/* Form the adjusted address. */
|
/* Form the adjusted address. */
|
||||||
if (GET_CODE (XEXP (ad, 0)) == PLUS)
|
if (GET_CODE (XEXP (ad, 0)) == PLUS)
|
||||||
ad = gen_rtx_PLUS (GET_MODE (ad),
|
ad = gen_rtx_PLUS (GET_MODE (ad),
|
||||||
@ -4972,12 +4985,13 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
|
|||||||
op_index == 0 ? addend : offset_reg);
|
op_index == 0 ? addend : offset_reg);
|
||||||
*loc = ad;
|
*loc = ad;
|
||||||
|
|
||||||
|
cls = base_reg_class (mode, MEM, GET_CODE (addend));
|
||||||
find_reloads_address_part (XEXP (ad, op_index),
|
find_reloads_address_part (XEXP (ad, op_index),
|
||||||
&XEXP (ad, op_index),
|
&XEXP (ad, op_index), cls,
|
||||||
MODE_BASE_REG_CLASS (mode),
|
|
||||||
GET_MODE (ad), opnum, type, ind_levels);
|
GET_MODE (ad), opnum, type, ind_levels);
|
||||||
find_reloads_address_1 (mode,
|
find_reloads_address_1 (mode,
|
||||||
XEXP (ad, 1 - op_index), 1,
|
XEXP (ad, 1 - op_index), 1, GET_CODE (ad),
|
||||||
|
GET_CODE (XEXP (ad, op_index)),
|
||||||
&XEXP (ad, 1 - op_index), opnum,
|
&XEXP (ad, 1 - op_index), opnum,
|
||||||
type, 0, insn);
|
type, 0, insn);
|
||||||
|
|
||||||
@ -5023,13 +5037,13 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
|
|||||||
loc = &XEXP (*loc, 0);
|
loc = &XEXP (*loc, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
find_reloads_address_part (ad, loc, MODE_BASE_REG_CLASS (mode),
|
find_reloads_address_part (ad, loc, base_reg_class (mode, MEM, SCRATCH),
|
||||||
Pmode, opnum, type, ind_levels);
|
Pmode, opnum, type, ind_levels);
|
||||||
return ! removed_and;
|
return ! removed_and;
|
||||||
}
|
}
|
||||||
|
|
||||||
return find_reloads_address_1 (mode, ad, 0, loc, opnum, type, ind_levels,
|
return find_reloads_address_1 (mode, ad, 0, MEM, SCRATCH, loc, opnum, type,
|
||||||
insn);
|
ind_levels, insn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find all pseudo regs appearing in AD
|
/* Find all pseudo regs appearing in AD
|
||||||
@ -5240,9 +5254,12 @@ update_auto_inc_notes (rtx insn ATTRIBUTE_UNUSED, int regno ATTRIBUTE_UNUSED,
|
|||||||
is strictly valid.)
|
is strictly valid.)
|
||||||
|
|
||||||
CONTEXT = 1 means we are considering regs as index regs,
|
CONTEXT = 1 means we are considering regs as index regs,
|
||||||
= 0 means we are considering them as base regs, = 2 means we
|
= 0 means we are considering them as base regs.
|
||||||
are considering them as base regs for REG + REG.
|
OUTER_CODE is the code of the enclosing RTX, typically a MEM, a PLUS,
|
||||||
|
or an autoinc code.
|
||||||
|
If CONTEXT == 0 and OUTER_CODE is a PLUS or LO_SUM, then INDEX_CODE
|
||||||
|
is the code of the index part of the address. Otherwise, pass SCRATCH
|
||||||
|
for this argument.
|
||||||
OPNUM and TYPE specify the purpose of any reloads made.
|
OPNUM and TYPE specify the purpose of any reloads made.
|
||||||
|
|
||||||
IND_LEVELS says how many levels of indirect addressing are
|
IND_LEVELS says how many levels of indirect addressing are
|
||||||
@ -5263,25 +5280,22 @@ update_auto_inc_notes (rtx insn ATTRIBUTE_UNUSED, int regno ATTRIBUTE_UNUSED,
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
|
find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
|
||||||
|
enum rtx_code outer_code, enum rtx_code index_code,
|
||||||
rtx *loc, int opnum, enum reload_type type,
|
rtx *loc, int opnum, enum reload_type type,
|
||||||
int ind_levels, rtx insn)
|
int ind_levels, rtx insn)
|
||||||
{
|
{
|
||||||
#define REG_OK_FOR_CONTEXT(CONTEXT, REGNO, MODE) \
|
#define REG_OK_FOR_CONTEXT(CONTEXT, REGNO, MODE, OUTER, INDEX) \
|
||||||
((CONTEXT) == 2 \
|
((CONTEXT) == 0 \
|
||||||
? REGNO_MODE_OK_FOR_REG_BASE_P (REGNO, MODE) \
|
? regno_ok_for_base_p (REGNO, MODE, OUTER, INDEX) \
|
||||||
: (CONTEXT) == 1 \
|
: REGNO_OK_FOR_INDEX_P (REGNO))
|
||||||
? REGNO_OK_FOR_INDEX_P (REGNO) \
|
|
||||||
: REGNO_MODE_OK_FOR_BASE_P (REGNO, MODE))
|
|
||||||
|
|
||||||
enum reg_class context_reg_class;
|
enum reg_class context_reg_class;
|
||||||
RTX_CODE code = GET_CODE (x);
|
RTX_CODE code = GET_CODE (x);
|
||||||
|
|
||||||
if (context == 2)
|
if (context == 1)
|
||||||
context_reg_class = MODE_BASE_REG_REG_CLASS (mode);
|
|
||||||
else if (context == 1)
|
|
||||||
context_reg_class = INDEX_REG_CLASS;
|
context_reg_class = INDEX_REG_CLASS;
|
||||||
else
|
else
|
||||||
context_reg_class = MODE_BASE_REG_CLASS (mode);
|
context_reg_class = base_reg_class (mode, outer_code, index_code);
|
||||||
|
|
||||||
switch (code)
|
switch (code)
|
||||||
{
|
{
|
||||||
@ -5338,74 +5352,90 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
|
|||||||
if (code0 == MULT || code0 == SIGN_EXTEND || code0 == TRUNCATE
|
if (code0 == MULT || code0 == SIGN_EXTEND || code0 == TRUNCATE
|
||||||
|| code0 == ZERO_EXTEND || code1 == MEM)
|
|| code0 == ZERO_EXTEND || code1 == MEM)
|
||||||
{
|
{
|
||||||
find_reloads_address_1 (mode, orig_op0, 1, &XEXP (x, 0), opnum,
|
find_reloads_address_1 (mode, orig_op0, 1, PLUS, SCRATCH,
|
||||||
type, ind_levels, insn);
|
&XEXP (x, 0), opnum, type, ind_levels,
|
||||||
find_reloads_address_1 (mode, orig_op1, 0, &XEXP (x, 1), opnum,
|
insn);
|
||||||
type, ind_levels, insn);
|
find_reloads_address_1 (mode, orig_op1, 0, PLUS, code0,
|
||||||
|
&XEXP (x, 1), opnum, type, ind_levels,
|
||||||
|
insn);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (code1 == MULT || code1 == SIGN_EXTEND || code1 == TRUNCATE
|
else if (code1 == MULT || code1 == SIGN_EXTEND || code1 == TRUNCATE
|
||||||
|| code1 == ZERO_EXTEND || code0 == MEM)
|
|| code1 == ZERO_EXTEND || code0 == MEM)
|
||||||
{
|
{
|
||||||
find_reloads_address_1 (mode, orig_op0, 0, &XEXP (x, 0), opnum,
|
find_reloads_address_1 (mode, orig_op0, 0, PLUS, code1,
|
||||||
type, ind_levels, insn);
|
&XEXP (x, 0), opnum, type, ind_levels,
|
||||||
find_reloads_address_1 (mode, orig_op1, 1, &XEXP (x, 1), opnum,
|
insn);
|
||||||
type, ind_levels, insn);
|
find_reloads_address_1 (mode, orig_op1, 1, PLUS, SCRATCH,
|
||||||
|
&XEXP (x, 1), opnum, type, ind_levels,
|
||||||
|
insn);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (code0 == CONST_INT || code0 == CONST
|
else if (code0 == CONST_INT || code0 == CONST
|
||||||
|| code0 == SYMBOL_REF || code0 == LABEL_REF)
|
|| code0 == SYMBOL_REF || code0 == LABEL_REF)
|
||||||
find_reloads_address_1 (mode, orig_op1, 0, &XEXP (x, 1), opnum,
|
find_reloads_address_1 (mode, orig_op1, 0, PLUS, code0,
|
||||||
type, ind_levels, insn);
|
&XEXP (x, 1), opnum, type, ind_levels,
|
||||||
|
insn);
|
||||||
|
|
||||||
else if (code1 == CONST_INT || code1 == CONST
|
else if (code1 == CONST_INT || code1 == CONST
|
||||||
|| code1 == SYMBOL_REF || code1 == LABEL_REF)
|
|| code1 == SYMBOL_REF || code1 == LABEL_REF)
|
||||||
find_reloads_address_1 (mode, orig_op0, 0, &XEXP (x, 0), opnum,
|
find_reloads_address_1 (mode, orig_op0, 0, PLUS, code1,
|
||||||
type, ind_levels, insn);
|
&XEXP (x, 0), opnum, type, ind_levels,
|
||||||
|
insn);
|
||||||
|
|
||||||
else if (code0 == REG && code1 == REG)
|
else if (code0 == REG && code1 == REG)
|
||||||
{
|
{
|
||||||
if (REG_OK_FOR_INDEX_P (op0)
|
if (REGNO_OK_FOR_INDEX_P (REGNO (op0))
|
||||||
&& REG_MODE_OK_FOR_REG_BASE_P (op1, mode))
|
&& regno_ok_for_base_p (REGNO (op1), mode, PLUS, REG))
|
||||||
return 0;
|
return 0;
|
||||||
else if (REG_OK_FOR_INDEX_P (op1)
|
else if (REGNO_OK_FOR_INDEX_P (REGNO (op1))
|
||||||
&& REG_MODE_OK_FOR_REG_BASE_P (op0, mode))
|
&& regno_ok_for_base_p (REGNO (op0), mode, PLUS, REG))
|
||||||
return 0;
|
return 0;
|
||||||
else if (REG_MODE_OK_FOR_REG_BASE_P (op1, mode))
|
else if (regno_ok_for_base_p (REGNO (op1), mode, PLUS, REG))
|
||||||
find_reloads_address_1 (mode, orig_op0, 1, &XEXP (x, 0), opnum,
|
find_reloads_address_1 (mode, orig_op0, 1, PLUS, SCRATCH,
|
||||||
type, ind_levels, insn);
|
&XEXP (x, 0), opnum, type, ind_levels,
|
||||||
else if (REG_MODE_OK_FOR_REG_BASE_P (op0, mode))
|
insn);
|
||||||
find_reloads_address_1 (mode, orig_op1, 1, &XEXP (x, 1), opnum,
|
else if (regno_ok_for_base_p (REGNO (op0), mode, PLUS, REG))
|
||||||
type, ind_levels, insn);
|
find_reloads_address_1 (mode, orig_op1, 1, PLUS, SCRATCH,
|
||||||
else if (REG_OK_FOR_INDEX_P (op1))
|
&XEXP (x, 1), opnum, type, ind_levels,
|
||||||
find_reloads_address_1 (mode, orig_op0, 2, &XEXP (x, 0), opnum,
|
insn);
|
||||||
type, ind_levels, insn);
|
else if (REGNO_OK_FOR_INDEX_P (REGNO (op1)))
|
||||||
else if (REG_OK_FOR_INDEX_P (op0))
|
find_reloads_address_1 (mode, orig_op0, 0, PLUS, REG,
|
||||||
find_reloads_address_1 (mode, orig_op1, 2, &XEXP (x, 1), opnum,
|
&XEXP (x, 0), opnum, type, ind_levels,
|
||||||
type, ind_levels, insn);
|
insn);
|
||||||
|
else if (REGNO_OK_FOR_INDEX_P (REGNO (op0)))
|
||||||
|
find_reloads_address_1 (mode, orig_op1, 0, PLUS, REG,
|
||||||
|
&XEXP (x, 1), opnum, type, ind_levels,
|
||||||
|
insn);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
find_reloads_address_1 (mode, orig_op0, 1, &XEXP (x, 0), opnum,
|
find_reloads_address_1 (mode, orig_op0, 1, PLUS, SCRATCH,
|
||||||
type, ind_levels, insn);
|
&XEXP (x, 0), opnum, type, ind_levels,
|
||||||
find_reloads_address_1 (mode, orig_op1, 0, &XEXP (x, 1), opnum,
|
insn);
|
||||||
type, ind_levels, insn);
|
find_reloads_address_1 (mode, orig_op1, 0, PLUS, REG,
|
||||||
|
&XEXP (x, 1), opnum, type, ind_levels,
|
||||||
|
insn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (code0 == REG)
|
else if (code0 == REG)
|
||||||
{
|
{
|
||||||
find_reloads_address_1 (mode, orig_op0, 1, &XEXP (x, 0), opnum,
|
find_reloads_address_1 (mode, orig_op0, 1, PLUS, SCRATCH,
|
||||||
type, ind_levels, insn);
|
&XEXP (x, 0), opnum, type, ind_levels,
|
||||||
find_reloads_address_1 (mode, orig_op1, 0, &XEXP (x, 1), opnum,
|
insn);
|
||||||
type, ind_levels, insn);
|
find_reloads_address_1 (mode, orig_op1, 0, PLUS, REG,
|
||||||
|
&XEXP (x, 1), opnum, type, ind_levels,
|
||||||
|
insn);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (code1 == REG)
|
else if (code1 == REG)
|
||||||
{
|
{
|
||||||
find_reloads_address_1 (mode, orig_op1, 1, &XEXP (x, 1), opnum,
|
find_reloads_address_1 (mode, orig_op1, 1, PLUS, SCRATCH,
|
||||||
type, ind_levels, insn);
|
&XEXP (x, 1), opnum, type, ind_levels,
|
||||||
find_reloads_address_1 (mode, orig_op0, 0, &XEXP (x, 0), opnum,
|
insn);
|
||||||
type, ind_levels, insn);
|
find_reloads_address_1 (mode, orig_op0, 0, PLUS, REG,
|
||||||
|
&XEXP (x, 0), opnum, type, ind_levels,
|
||||||
|
insn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5416,6 +5446,7 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
|
|||||||
{
|
{
|
||||||
rtx op0 = XEXP (x, 0);
|
rtx op0 = XEXP (x, 0);
|
||||||
rtx op1 = XEXP (x, 1);
|
rtx op1 = XEXP (x, 1);
|
||||||
|
enum rtx_code index_code;
|
||||||
int regno;
|
int regno;
|
||||||
int reloadnum;
|
int reloadnum;
|
||||||
|
|
||||||
@ -5434,12 +5465,14 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
|
|||||||
register with its equivalent constant where applicable. */
|
register with its equivalent constant where applicable. */
|
||||||
if (REG_P (XEXP (op1, 1)))
|
if (REG_P (XEXP (op1, 1)))
|
||||||
if (!REGNO_OK_FOR_INDEX_P (REGNO (XEXP (op1, 1))))
|
if (!REGNO_OK_FOR_INDEX_P (REGNO (XEXP (op1, 1))))
|
||||||
find_reloads_address_1 (mode, XEXP (op1, 1), 1, &XEXP (op1, 1),
|
find_reloads_address_1 (mode, XEXP (op1, 1), 1, code, SCRATCH,
|
||||||
opnum, type, ind_levels, insn);
|
&XEXP (op1, 1), opnum, type, ind_levels,
|
||||||
|
insn);
|
||||||
|
|
||||||
gcc_assert (REG_P (XEXP (op1, 0)));
|
gcc_assert (REG_P (XEXP (op1, 0)));
|
||||||
|
|
||||||
regno = REGNO (XEXP (op1, 0));
|
regno = REGNO (XEXP (op1, 0));
|
||||||
|
index_code = GET_CODE (XEXP (op1, 1));
|
||||||
|
|
||||||
/* A register that is incremented cannot be constant! */
|
/* A register that is incremented cannot be constant! */
|
||||||
gcc_assert (regno < FIRST_PSEUDO_REGISTER
|
gcc_assert (regno < FIRST_PSEUDO_REGISTER
|
||||||
@ -5466,12 +5499,13 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
|
|||||||
ind_levels, insn);
|
ind_levels, insn);
|
||||||
|
|
||||||
/* Then reload the memory location into a base
|
/* Then reload the memory location into a base
|
||||||
register. */
|
register. */
|
||||||
reloadnum = push_reload (tem, tem, &XEXP (x, 0),
|
reloadnum = push_reload (tem, tem, &XEXP (x, 0),
|
||||||
&XEXP (op1, 0),
|
&XEXP (op1, 0),
|
||||||
MODE_BASE_REG_CLASS (mode),
|
base_reg_class (mode, code,
|
||||||
GET_MODE (x), GET_MODE (x), 0,
|
index_code),
|
||||||
0, opnum, RELOAD_OTHER);
|
GET_MODE (x), GET_MODE (x), 0,
|
||||||
|
0, opnum, RELOAD_OTHER);
|
||||||
|
|
||||||
update_auto_inc_notes (this_insn, regno, reloadnum);
|
update_auto_inc_notes (this_insn, regno, reloadnum);
|
||||||
return 0;
|
return 0;
|
||||||
@ -5482,13 +5516,13 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
|
|||||||
regno = reg_renumber[regno];
|
regno = reg_renumber[regno];
|
||||||
|
|
||||||
/* We require a base register here... */
|
/* We require a base register here... */
|
||||||
if (!REGNO_MODE_OK_FOR_BASE_P (regno, GET_MODE (x)))
|
if (!regno_ok_for_base_p (regno, GET_MODE (x), code, index_code))
|
||||||
{
|
{
|
||||||
reloadnum = push_reload (XEXP (op1, 0), XEXP (x, 0),
|
reloadnum = push_reload (XEXP (op1, 0), XEXP (x, 0),
|
||||||
&XEXP (op1, 0), &XEXP (x, 0),
|
&XEXP (op1, 0), &XEXP (x, 0),
|
||||||
MODE_BASE_REG_CLASS (mode),
|
base_reg_class (mode, code, index_code),
|
||||||
GET_MODE (x), GET_MODE (x), 0, 0,
|
GET_MODE (x), GET_MODE (x), 0, 0,
|
||||||
opnum, RELOAD_OTHER);
|
opnum, RELOAD_OTHER);
|
||||||
|
|
||||||
update_auto_inc_notes (this_insn, regno, reloadnum);
|
update_auto_inc_notes (this_insn, regno, reloadnum);
|
||||||
return 0;
|
return 0;
|
||||||
@ -5546,7 +5580,8 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
|
|||||||
if (reg_renumber[regno] >= 0)
|
if (reg_renumber[regno] >= 0)
|
||||||
regno = reg_renumber[regno];
|
regno = reg_renumber[regno];
|
||||||
if (regno >= FIRST_PSEUDO_REGISTER
|
if (regno >= FIRST_PSEUDO_REGISTER
|
||||||
|| !REG_OK_FOR_CONTEXT (context, regno, mode))
|
|| !REG_OK_FOR_CONTEXT (context, regno, mode, outer_code,
|
||||||
|
index_code))
|
||||||
{
|
{
|
||||||
int reloadnum;
|
int reloadnum;
|
||||||
|
|
||||||
@ -5654,7 +5689,7 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
|
|||||||
(or perhaps even a different part of an outer expression), should
|
(or perhaps even a different part of an outer expression), should
|
||||||
define LEGITIMIZE_RELOAD_ADDRESS. */
|
define LEGITIMIZE_RELOAD_ADDRESS. */
|
||||||
find_reloads_address_1 (GET_MODE (XEXP (x, 0)), XEXP (x, 0),
|
find_reloads_address_1 (GET_MODE (XEXP (x, 0)), XEXP (x, 0),
|
||||||
context, &XEXP (x, 0), opnum,
|
context, code, SCRATCH, &XEXP (x, 0), opnum,
|
||||||
type, ind_levels, insn);
|
type, ind_levels, insn);
|
||||||
push_reload (x, NULL_RTX, loc, (rtx*) 0,
|
push_reload (x, NULL_RTX, loc, (rtx*) 0,
|
||||||
context_reg_class,
|
context_reg_class,
|
||||||
@ -5722,7 +5757,8 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
|
|||||||
regno = reg_renumber[regno];
|
regno = reg_renumber[regno];
|
||||||
|
|
||||||
if (regno >= FIRST_PSEUDO_REGISTER
|
if (regno >= FIRST_PSEUDO_REGISTER
|
||||||
|| !REG_OK_FOR_CONTEXT (context, regno, mode))
|
|| !REG_OK_FOR_CONTEXT (context, regno, mode, outer_code,
|
||||||
|
index_code))
|
||||||
{
|
{
|
||||||
push_reload (x, NULL_RTX, loc, (rtx*) 0,
|
push_reload (x, NULL_RTX, loc, (rtx*) 0,
|
||||||
context_reg_class,
|
context_reg_class,
|
||||||
@ -5754,7 +5790,8 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
|
|||||||
{
|
{
|
||||||
int regno ATTRIBUTE_UNUSED = subreg_regno (x);
|
int regno ATTRIBUTE_UNUSED = subreg_regno (x);
|
||||||
|
|
||||||
if (! REG_OK_FOR_CONTEXT (context, regno, mode))
|
if (!REG_OK_FOR_CONTEXT (context, regno, mode, outer_code,
|
||||||
|
index_code))
|
||||||
{
|
{
|
||||||
push_reload (x, NULL_RTX, loc, (rtx*) 0,
|
push_reload (x, NULL_RTX, loc, (rtx*) 0,
|
||||||
context_reg_class,
|
context_reg_class,
|
||||||
@ -5792,8 +5829,10 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
|
|||||||
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
|
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
if (fmt[i] == 'e')
|
if (fmt[i] == 'e')
|
||||||
find_reloads_address_1 (mode, XEXP (x, i), context, &XEXP (x, i),
|
/* Pass SCRATCH for INDEX_CODE, since CODE can never be a PLUS once
|
||||||
opnum, type, ind_levels, insn);
|
we get here. */
|
||||||
|
find_reloads_address_1 (mode, XEXP (x, i), context, code, SCRATCH,
|
||||||
|
&XEXP (x, i), opnum, type, ind_levels, insn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
|||||||
#include "expr.h"
|
#include "expr.h"
|
||||||
#include "optabs.h"
|
#include "optabs.h"
|
||||||
#include "regs.h"
|
#include "regs.h"
|
||||||
|
#include "addresses.h"
|
||||||
#include "basic-block.h"
|
#include "basic-block.h"
|
||||||
#include "reload.h"
|
#include "reload.h"
|
||||||
#include "recog.h"
|
#include "recog.h"
|
||||||
@ -1375,7 +1376,7 @@ maybe_fix_stack_asms (void)
|
|||||||
|
|
||||||
case 'p':
|
case 'p':
|
||||||
cls = (int) reg_class_subunion[cls]
|
cls = (int) reg_class_subunion[cls]
|
||||||
[(int) MODE_BASE_REG_CLASS (VOIDmode)];
|
[(int) base_reg_class (VOIDmode, ADDRESS, SCRATCH)];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'g':
|
case 'g':
|
||||||
@ -1386,7 +1387,7 @@ maybe_fix_stack_asms (void)
|
|||||||
default:
|
default:
|
||||||
if (EXTRA_ADDRESS_CONSTRAINT (c, p))
|
if (EXTRA_ADDRESS_CONSTRAINT (c, p))
|
||||||
cls = (int) reg_class_subunion[cls]
|
cls = (int) reg_class_subunion[cls]
|
||||||
[(int) MODE_BASE_REG_CLASS (VOIDmode)];
|
[(int) base_reg_class (VOIDmode, ADDRESS, SCRATCH)];
|
||||||
else
|
else
|
||||||
cls = (int) reg_class_subunion[cls]
|
cls = (int) reg_class_subunion[cls]
|
||||||
[(int) REG_CLASS_FROM_CONSTRAINT (c, p)];
|
[(int) REG_CLASS_FROM_CONSTRAINT (c, p)];
|
||||||
|
@ -36,6 +36,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
|||||||
#include "tree-flow.h"
|
#include "tree-flow.h"
|
||||||
#include "timevar.h"
|
#include "timevar.h"
|
||||||
#include "output.h"
|
#include "output.h"
|
||||||
|
#include "addresses.h"
|
||||||
|
|
||||||
/* Sequence abstraction:
|
/* Sequence abstraction:
|
||||||
|
|
||||||
@ -689,8 +690,9 @@ recompute_gain_for_pattern_seq (pattern_seq pseq)
|
|||||||
#ifdef REGNO_OK_FOR_INDIRECT_JUMP_P
|
#ifdef REGNO_OK_FOR_INDIRECT_JUMP_P
|
||||||
|| (!REGNO_OK_FOR_INDIRECT_JUMP_P (i, Pmode))
|
|| (!REGNO_OK_FOR_INDIRECT_JUMP_P (i, Pmode))
|
||||||
#else
|
#else
|
||||||
|| (!REGNO_MODE_OK_FOR_BASE_P (i, Pmode))
|
|| (!ok_for_base_p_1 (i, Pmode, MEM, SCRATCH))
|
||||||
|| (!reg_class_subset_p (REGNO_REG_CLASS (i), BASE_REG_CLASS))
|
|| (!reg_class_subset_p (REGNO_REG_CLASS (i),
|
||||||
|
base_reg_class (VOIDmode, MEM, SCRATCH)))
|
||||||
#endif
|
#endif
|
||||||
|| (hascall && call_used_regs[i])
|
|| (hascall && call_used_regs[i])
|
||||||
|| (!call_used_regs[i] && !regs_ever_live[i]))
|
|| (!call_used_regs[i] && !regs_ever_live[i]))
|
||||||
|
Loading…
Reference in New Issue
Block a user