m32r.h (REG_OK_FOR_BASE_P, [...]): Remove macros.
* config/m32r/m32r.h (REG_OK_FOR_BASE_P, REG_OK_FOR_INDEX_P, RTX_OK_FOR_BASE_P, RTX_OK_FOR_OFFSET_P, LEGITIMATE_OFFSET_ADDRESS_P, LEGITIMATE_LO_SUM_ADDRESS_P, LOAD_POSTINC_P, STORE_PREINC_PREDEC_P, GO_IF_LEGITIMATE_ADDRESS): Remove macros. * config/m32r/m32r.c (TARGET_LEGITIMATE_ADDRESS_P): Define. (m32r_rtx_ok_for_base_p, m32r_rtx_ok_for_offset_p, m32r_legitimate_offset_addres_p, m32r_legitimate_lo_sum_addres_p, m32r_load_postinc_p, m32r_store_preinc_predec_p, m32r_legitimate_address_p): New functions. * config/m32r/constraints.md (constraint "S"): Don't use STORE_PREINC_PREDEC_P. (constraint "U"): Don't use LOAD_POSTINC_P. From-SVN: r170278
This commit is contained in:
parent
7efcf910ee
commit
4bf7ff7ebd
@ -1,3 +1,18 @@
|
||||
2011-02-18 Anatoly Sokolov <aesok@post.ru>
|
||||
|
||||
* config/m32r/m32r.h (REG_OK_FOR_BASE_P, REG_OK_FOR_INDEX_P,
|
||||
RTX_OK_FOR_BASE_P, RTX_OK_FOR_OFFSET_P, LEGITIMATE_OFFSET_ADDRESS_P,
|
||||
LEGITIMATE_LO_SUM_ADDRESS_P, LOAD_POSTINC_P, STORE_PREINC_PREDEC_P,
|
||||
GO_IF_LEGITIMATE_ADDRESS): Remove macros.
|
||||
* config/m32r/m32r.c (TARGET_LEGITIMATE_ADDRESS_P): Define.
|
||||
(m32r_rtx_ok_for_base_p, m32r_rtx_ok_for_offset_p,
|
||||
m32r_legitimate_offset_addres_p, m32r_legitimate_lo_sum_addres_p,
|
||||
m32r_load_postinc_p, m32r_store_preinc_predec_p,
|
||||
m32r_legitimate_address_p): New functions.
|
||||
* config/m32r/constraints.md (constraint "S"): Don't use
|
||||
STORE_PREINC_PREDEC_P.
|
||||
(constraint "U"): Don't use LOAD_POSTINC_P.
|
||||
|
||||
2011-02-18 Chung-Lin Tang <cltang@codesourcery.com>
|
||||
|
||||
PR rtl-optimization/46178
|
||||
|
@ -1,5 +1,5 @@
|
||||
;; Constraint definitions for Renesas M32R cpu for GNU C compiler
|
||||
;; Copyright (C) 2007 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2007, 2011 Free Software Foundation, Inc.
|
||||
;;
|
||||
;; This file is part of GCC.
|
||||
;;
|
||||
@ -118,7 +118,12 @@
|
||||
(define_constraint "S"
|
||||
"A store with pre {inc,dec}rement."
|
||||
(and (match_code "mem")
|
||||
(match_test "STORE_PREINC_PREDEC_P (GET_MODE (op), XEXP (op, 0))")))
|
||||
(match_test "mode == SImode || mode == SFmode")
|
||||
(match_code "pre_inc,pre_dec" "0")
|
||||
(match_code "reg" "00")
|
||||
(match_test "GPR_P (REGNO (XEXP (XEXP (op, 0), 0)))
|
||||
|| REGNO (XEXP (XEXP (op, 0), 0)) == ARG_POINTER_REGNUM
|
||||
|| ! HARD_REGISTER_P (XEXP (XEXP (op, 0), 0))")))
|
||||
|
||||
(define_constraint "T"
|
||||
"An indirect of a pointer."
|
||||
@ -128,7 +133,12 @@
|
||||
(define_constraint "U"
|
||||
"A load with post increment."
|
||||
(and (match_code "mem")
|
||||
(match_test "LOAD_POSTINC_P (GET_MODE (op), XEXP (op, 0))")))
|
||||
(match_test "mode == SImode || mode == SFmode")
|
||||
(match_code "post_inc" "0")
|
||||
(match_code "reg" "00")
|
||||
(match_test "GPR_P (REGNO (XEXP (XEXP (op, 0), 0)))
|
||||
|| REGNO (XEXP (XEXP (op, 0), 0)) == ARG_POINTER_REGNUM
|
||||
|| ! HARD_REGISTER_P (XEXP (XEXP (op, 0), 0))")))
|
||||
|
||||
(define_constraint "W"
|
||||
"zero immediate."
|
||||
|
@ -66,6 +66,7 @@ static void m32r_option_override (void);
|
||||
static void init_reg_tables (void);
|
||||
static void block_move_call (rtx, rtx, rtx);
|
||||
static int m32r_is_insn (rtx);
|
||||
static bool m32r_legitimate_address_p (enum machine_mode, rtx, bool);
|
||||
static rtx m32r_legitimize_address (rtx, rtx, enum machine_mode);
|
||||
static bool m32r_mode_dependent_address_p (const_rtx);
|
||||
static tree m32r_handle_model_attribute (tree *, tree, tree, int, bool *);
|
||||
@ -124,6 +125,8 @@ static const struct default_options m32r_option_optimization_table[] =
|
||||
#undef TARGET_ATTRIBUTE_TABLE
|
||||
#define TARGET_ATTRIBUTE_TABLE m32r_attribute_table
|
||||
|
||||
#undef TARGET_LEGITIMATE_ADDRESS_P
|
||||
#define TARGET_LEGITIMATE_ADDRESS_P m32r_legitimate_address_p
|
||||
#undef TARGET_LEGITIMIZE_ADDRESS
|
||||
#define TARGET_LEGITIMIZE_ADDRESS m32r_legitimize_address
|
||||
#undef TARGET_MODE_DEPENDENT_ADDRESS_P
|
||||
@ -2844,6 +2847,107 @@ m32r_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
|
||||
GEN_INT (3), SImode);
|
||||
}
|
||||
|
||||
/* True if X is a reg that can be used as a base reg. */
|
||||
|
||||
static bool
|
||||
m32r_rtx_ok_for_base_p (const_rtx x, bool strict)
|
||||
{
|
||||
if (! REG_P (x))
|
||||
return false;
|
||||
|
||||
if (strict)
|
||||
{
|
||||
if (GPR_P (REGNO (x)))
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GPR_P (REGNO (x))
|
||||
|| REGNO (x) == ARG_POINTER_REGNUM
|
||||
|| ! HARD_REGISTER_P (x))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
m32r_rtx_ok_for_offset_p (const_rtx x)
|
||||
{
|
||||
return (CONST_INT_P (x) && INT16_P (INTVAL (x)));
|
||||
}
|
||||
|
||||
static inline bool
|
||||
m32r_legitimate_offset_addres_p (enum machine_mode mode ATTRIBUTE_UNUSED,
|
||||
const_rtx x, bool strict)
|
||||
{
|
||||
if (GET_CODE (x) == PLUS
|
||||
&& m32r_rtx_ok_for_base_p (XEXP (x, 0), strict)
|
||||
&& m32r_rtx_ok_for_offset_p (XEXP (x, 1)))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* For LO_SUM addresses, do not allow them if the MODE is > 1 word,
|
||||
since more than one instruction will be required. */
|
||||
|
||||
static inline bool
|
||||
m32r_legitimate_lo_sum_addres_p (enum machine_mode mode, const_rtx x,
|
||||
bool strict)
|
||||
{
|
||||
if (GET_CODE (x) == LO_SUM
|
||||
&& (mode != BLKmode && GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
|
||||
&& m32r_rtx_ok_for_base_p (XEXP (x, 0), strict)
|
||||
&& CONSTANT_P (XEXP (x, 1)))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Is this a load and increment operation. */
|
||||
|
||||
static inline bool
|
||||
m32r_load_postinc_p (enum machine_mode mode, const_rtx x, bool strict)
|
||||
{
|
||||
if ((mode == SImode || mode == SFmode)
|
||||
&& GET_CODE (x) == POST_INC
|
||||
&& REG_P (XEXP (x, 0))
|
||||
&& m32r_rtx_ok_for_base_p (XEXP (x, 0), strict))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Is this an increment/decrement and store operation. */
|
||||
|
||||
static inline bool
|
||||
m32r_store_preinc_predec_p (enum machine_mode mode, const_rtx x, bool strict)
|
||||
{
|
||||
if ((mode == SImode || mode == SFmode)
|
||||
&& (GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
|
||||
&& REG_P (XEXP (x, 0)) \
|
||||
&& m32r_rtx_ok_for_base_p (XEXP (x, 0), strict))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Implement TARGET_LEGITIMATE_ADDRESS_P. */
|
||||
|
||||
static bool
|
||||
m32r_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
|
||||
{
|
||||
if (m32r_rtx_ok_for_base_p (x, strict)
|
||||
|| m32r_legitimate_offset_addres_p (mode, x, strict)
|
||||
|| m32r_legitimate_lo_sum_addres_p (mode, x, strict)
|
||||
|| m32r_load_postinc_p (mode, x, strict)
|
||||
|| m32r_store_preinc_predec_p (mode, x, strict))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
m32r_conditional_register_usage (void)
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* Definitions of target machine for GNU compiler, Renesas M32R cpu.
|
||||
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
||||
2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
|
||||
2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
@ -858,99 +858,6 @@ L2: .word STATIC
|
||||
&& (GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF || GET_CODE (XEXP (XEXP (X, 0), 0)) == LABEL_REF) \
|
||||
&& CONST_INT_P (XEXP (XEXP (X, 0), 1)) \
|
||||
&& (unsigned HOST_WIDE_INT) INTVAL (XEXP (XEXP (X, 0), 1)) > 32767))
|
||||
|
||||
/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
|
||||
and check its validity for a certain class.
|
||||
We have two alternate definitions for each of them.
|
||||
The usual definition accepts all pseudo regs; the other rejects
|
||||
them unless they have been allocated suitable hard regs.
|
||||
The symbol REG_OK_STRICT causes the latter definition to be used.
|
||||
|
||||
Most source files want to accept pseudo regs in the hope that
|
||||
they will get allocated to the class that the insn wants them to be in.
|
||||
Source files for reload pass need to be strict.
|
||||
After reload, it makes no difference, since pseudo regs have
|
||||
been eliminated by then. */
|
||||
|
||||
#ifdef REG_OK_STRICT
|
||||
|
||||
/* Nonzero if X is a hard reg that can be used as a base reg. */
|
||||
#define REG_OK_FOR_BASE_P(X) GPR_P (REGNO (X))
|
||||
/* Nonzero if X is a hard reg that can be used as an index. */
|
||||
#define REG_OK_FOR_INDEX_P(X) REG_OK_FOR_BASE_P (X)
|
||||
|
||||
#else
|
||||
|
||||
/* Nonzero if X is a hard reg that can be used as a base reg
|
||||
or if it is a pseudo reg. */
|
||||
#define REG_OK_FOR_BASE_P(X) \
|
||||
(GPR_P (REGNO (X)) \
|
||||
|| (REGNO (X)) == ARG_POINTER_REGNUM \
|
||||
|| REGNO (X) >= FIRST_PSEUDO_REGISTER)
|
||||
/* Nonzero if X is a hard reg that can be used as an index
|
||||
or if it is a pseudo reg. */
|
||||
#define REG_OK_FOR_INDEX_P(X) REG_OK_FOR_BASE_P (X)
|
||||
|
||||
#endif
|
||||
|
||||
/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
|
||||
that is a valid memory address for an instruction.
|
||||
The MODE argument is the machine mode for the MEM expression
|
||||
that wants to use this address. */
|
||||
|
||||
/* Local to this file. */
|
||||
#define RTX_OK_FOR_BASE_P(X) (REG_P (X) && REG_OK_FOR_BASE_P (X))
|
||||
|
||||
/* Local to this file. */
|
||||
#define RTX_OK_FOR_OFFSET_P(X) \
|
||||
(CONST_INT_P (X) && INT16_P (INTVAL (X)))
|
||||
|
||||
/* Local to this file. */
|
||||
#define LEGITIMATE_OFFSET_ADDRESS_P(MODE, X) \
|
||||
(GET_CODE (X) == PLUS \
|
||||
&& RTX_OK_FOR_BASE_P (XEXP (X, 0)) \
|
||||
&& RTX_OK_FOR_OFFSET_P (XEXP (X, 1)))
|
||||
|
||||
/* Local to this file. */
|
||||
/* For LO_SUM addresses, do not allow them if the MODE is > 1 word,
|
||||
since more than one instruction will be required. */
|
||||
#define LEGITIMATE_LO_SUM_ADDRESS_P(MODE, X) \
|
||||
(GET_CODE (X) == LO_SUM \
|
||||
&& (MODE != BLKmode && GET_MODE_SIZE (MODE) <= UNITS_PER_WORD)\
|
||||
&& RTX_OK_FOR_BASE_P (XEXP (X, 0)) \
|
||||
&& CONSTANT_P (XEXP (X, 1)))
|
||||
|
||||
/* Local to this file. */
|
||||
/* Is this a load and increment operation. */
|
||||
#define LOAD_POSTINC_P(MODE, X) \
|
||||
(((MODE) == SImode || (MODE) == SFmode) \
|
||||
&& GET_CODE (X) == POST_INC \
|
||||
&& REG_P (XEXP (X, 0)) \
|
||||
&& RTX_OK_FOR_BASE_P (XEXP (X, 0)))
|
||||
|
||||
/* Local to this file. */
|
||||
/* Is this an increment/decrement and store operation. */
|
||||
#define STORE_PREINC_PREDEC_P(MODE, X) \
|
||||
(((MODE) == SImode || (MODE) == SFmode) \
|
||||
&& (GET_CODE (X) == PRE_INC || GET_CODE (X) == PRE_DEC) \
|
||||
&& REG_P (XEXP (X, 0)) \
|
||||
&& RTX_OK_FOR_BASE_P (XEXP (X, 0)))
|
||||
|
||||
#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
|
||||
do \
|
||||
{ \
|
||||
if (RTX_OK_FOR_BASE_P (X)) \
|
||||
goto ADDR; \
|
||||
if (LEGITIMATE_OFFSET_ADDRESS_P ((MODE), (X))) \
|
||||
goto ADDR; \
|
||||
if (LEGITIMATE_LO_SUM_ADDRESS_P ((MODE), (X))) \
|
||||
goto ADDR; \
|
||||
if (LOAD_POSTINC_P ((MODE), (X))) \
|
||||
goto ADDR; \
|
||||
if (STORE_PREINC_PREDEC_P ((MODE), (X))) \
|
||||
goto ADDR; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* Condition code usage. */
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user