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:
Anatoly Sokolov 2011-02-18 20:41:59 +03:00 committed by Anatoly Sokolov
parent 7efcf910ee
commit 4bf7ff7ebd
4 changed files with 133 additions and 97 deletions

View File

@ -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

View File

@ -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."

View File

@ -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)
{

View File

@ -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. */