Commit 41700fc3 by Hariharan Sandanagobalane Committed by Hariharan Sandanagobalane

picochip.c (picochip_legitimize_address): Define.

        * config/picochip/picochip.c (picochip_legitimize_address): Define.
        Use this function to do machine-specific conversion.
        (picochip_legitimize_reload_address): Likewise.
        (picochip_legitimate_address_p): Check valid base register only if
        strict.
        (picochip_check_conditional_copy): Check for modw only if opnd is
        register.
        * config/picochip/picochip.h (LEGITIMIZE_RELOAD_ADDRESS): Use this
        to call the function in c.
        * config/picochip/picochip-protos.h
        (picochip_legitimize_reload_address): Define.
        * config/picochip/picochip.md (supported_compare1): Define.

From-SVN: r158927
parent 8b4765bf
2010-04-30 Hariharan Sandanagobalane <hariharan@picochip.com>
* config/picochip/picochip.c (picochip_legitimize_address): Define.
Use this function to do machine-specific conversion.
(picochip_legitimize_reload_address): Likewise.
(picochip_legitimate_address_p): Check valid base register only if
strict.
(picochip_check_conditional_copy): Check for modw only if opnd is
register.
* config/picochip/picochip.h (LEGITIMIZE_RELOAD_ADDRESS): Use this
to call the function in c.
* config/picochip/picochip-protos.h
(picochip_legitimize_reload_address): Define.
* config/picochip/picochip.md (supported_compare1): Define.
2010-04-30 Jan Hubicka <jh@suse.cz> 2010-04-30 Jan Hubicka <jh@suse.cz>
* cgraph.h (cgraph_local_info): Remove for_functions_valid. * cgraph.h (cgraph_local_info): Remove for_functions_valid.
......
...@@ -99,6 +99,10 @@ extern rtx picochip_struct_value_rtx(tree fntype ATTRIBUTE_UNUSED, ...@@ -99,6 +99,10 @@ extern rtx picochip_struct_value_rtx(tree fntype ATTRIBUTE_UNUSED,
#endif /* RTX_CODE inside TREE_CODE */ #endif /* RTX_CODE inside TREE_CODE */
extern int picochip_legitimize_reload_address (rtx *x, enum machine_mode mode,
int opnum, int type, int ind_levels);
void picochip_output_ascii (FILE * file, const char *str, int length); void picochip_output_ascii (FILE * file, const char *str, int length);
extern int picochip_hard_regno_mode_ok (int regno, enum machine_mode mode); extern int picochip_hard_regno_mode_ok (int regno, enum machine_mode mode);
......
...@@ -96,6 +96,10 @@ bool picochip_rtx_costs (rtx x, int code, int outer_code, int* total, bool speed ...@@ -96,6 +96,10 @@ bool picochip_rtx_costs (rtx x, int code, int outer_code, int* total, bool speed
bool picochip_return_in_memory(const_tree type, bool picochip_return_in_memory(const_tree type,
const_tree fntype ATTRIBUTE_UNUSED); const_tree fntype ATTRIBUTE_UNUSED);
bool picochip_legitimate_address_p (enum machine_mode, rtx, bool); bool picochip_legitimate_address_p (enum machine_mode, rtx, bool);
rtx picochip_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
enum machine_mode mode);
int picochip_legitimize_reload_address (rtx *x, enum machine_mode mode,
int opnum, int type, int ind_levels);
rtx picochip_struct_value_rtx(tree fntype ATTRIBUTE_UNUSED, int incoming ATTRIBUTE_UNUSED); rtx picochip_struct_value_rtx(tree fntype ATTRIBUTE_UNUSED, int incoming ATTRIBUTE_UNUSED);
rtx picochip_function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED, rtx picochip_function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED,
...@@ -279,6 +283,9 @@ static char picochip_get_vliw_alu_id (void); ...@@ -279,6 +283,9 @@ static char picochip_get_vliw_alu_id (void);
#undef TARGET_LEGITIMATE_ADDRESS_P #undef TARGET_LEGITIMATE_ADDRESS_P
#define TARGET_LEGITIMATE_ADDRESS_P picochip_legitimate_address_p #define TARGET_LEGITIMATE_ADDRESS_P picochip_legitimate_address_p
#undef TARGET_LEGITIMIZE_ADDRESS
#define TARGET_LEGITIMIZE_ADDRESS picochip_legitimize_address
/* Loading and storing QImode values to and from memory /* Loading and storing QImode values to and from memory
usually requires a scratch register. */ usually requires a scratch register. */
#undef TARGET_SECONDARY_RELOAD #undef TARGET_SECONDARY_RELOAD
...@@ -1268,9 +1275,13 @@ picochip_legitimate_address_p (enum machine_mode mode, rtx x, bool strict) ...@@ -1268,9 +1275,13 @@ picochip_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
{ {
rtx base = XEXP (x, 0); rtx base = XEXP (x, 0);
rtx offset = XEXP (x, 1); rtx offset = XEXP (x, 1);
if (strict && !REGNO_OK_FOR_BASE_P (REGNO(base)))
{
valid = 0;
break;
}
valid = (REG == GET_CODE (base) && valid = (REG == GET_CODE (base) &&
REGNO_OK_FOR_BASE_P (REGNO(base)) &&
picochip_legitimate_address_register (base, strict) && picochip_legitimate_address_register (base, strict) &&
CONST_INT == GET_CODE (offset) && CONST_INT == GET_CODE (offset) &&
picochip_const_ok_for_base (mode, REGNO (base), picochip_const_ok_for_base (mode, REGNO (base),
...@@ -1311,6 +1322,144 @@ picochip_legitimate_address_p (enum machine_mode mode, rtx x, bool strict) ...@@ -1311,6 +1322,144 @@ picochip_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
} }
/* For all memory operations, picochip allows a uconst4 offset value. It
is hence beneficial to turn an
addr = <reg + long_const>
ld/st addr
into
X = reg + long_const & FFF0
diff = long_const - (long_const & FFF0)
ld/st <X + diff>
X can be reused in subsequent memory operations.
*/
rtx
picochip_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
enum machine_mode mode)
{
if (!optimize)
return x;
unsigned mask_val;
// Depending on mode, the offsets allowed are either 16/32/64.
switch (mode)
{
case QImode:
mask_val = 0xFFF0;
break;
case HImode:
mask_val = 0xFFE0;
break;
case SImode:
mask_val = 0xFFC0;
break;
default:
return x;
}
if (GET_CODE (x) == PLUS
&& GET_CODE (XEXP (x, 0)) == REG
&& GET_CODE (XEXP (x, 1)) == CONST_INT)
{
int offset = INTVAL (XEXP (x, 1));
// Ignore cases with negative offsets.
if (offset < 0)
return x;
int high_val = offset & mask_val;
int low_val = offset - high_val;
if (high_val != 0)
{
rtx temp_reg = force_reg (Pmode, gen_rtx_PLUS (Pmode, XEXP (x, 0), GEN_INT(high_val)));
x = gen_rtx_PLUS (Pmode, temp_reg, GEN_INT(low_val));
return x;
}
}
return x;
}
/* For all memory operations, picochip allows a uconst4 offset value. It
is hence beneficial to turn an
addr = <reg + long_const>
ld/st addr
into
X = reg + long_const & FFF0
diff = long_const - (long_const & FFF0)
ld/st <X + diff>
X can be reused in subsequent memory operations.
*/
int
picochip_legitimize_reload_address (rtx *x,
enum machine_mode mode,
int opnum, int type,
int ind_levels ATTRIBUTE_UNUSED)
{
if (picochip_symbol_offset(*x))
{
*x = gen_rtx_CONST(mode, *x);
return 0;
}
if (!optimize)
return 0;
/* We should recognise addresses that we created.*/
if (GET_CODE (*x) == PLUS
&& GET_CODE (XEXP (*x, 0)) == PLUS
&& GET_CODE (XEXP (XEXP (*x, 0), 0)) == REG
&& GET_CODE (XEXP (XEXP (*x, 0), 1)) == CONST_INT
&& GET_CODE (XEXP (*x, 1)) == CONST_INT)
{
push_reload (XEXP (*x, 0), NULL_RTX, &XEXP (*x, 0), NULL,
BASE_REG_CLASS, GET_MODE (*x), VOIDmode, 0, 0,
opnum, (enum reload_type)type);
return 1;
}
unsigned mask_val;
// Depending on mode, the offsets allowed are either 16/32/64.
switch (mode)
{
case QImode:
mask_val = 0xFFF0;
break;
case HImode:
mask_val = 0xFFE0;
break;
case SImode:
mask_val = 0xFFC0;
break;
default:
return 0;
}
if (GET_CODE (*x) == PLUS
&& GET_CODE (XEXP (*x, 0)) == REG
&& GET_CODE (XEXP (*x, 1)) == CONST_INT)
{
int offset = INTVAL (XEXP (*x, 1));
// Ignore cases with negative offsets.
if (offset < 0)
return 0;
int high_val = offset & mask_val;
int low_val = offset - high_val;
if (high_val != 0)
{
rtx temp_reg = gen_rtx_PLUS (Pmode, XEXP (*x, 0), GEN_INT(high_val));
*x = gen_rtx_PLUS (Pmode, temp_reg, GEN_INT(low_val));
push_reload (XEXP (*x, 0), NULL_RTX, &XEXP (*x, 0), NULL,
BASE_REG_CLASS, GET_MODE (*x), VOIDmode, 0, 0,
opnum, (enum reload_type)type);
return 1;
}
}
return 0;
}
/* Detect an rtx which matches (plus (symbol_ref) (const_int)). */ /* Detect an rtx which matches (plus (symbol_ref) (const_int)). */
int int
picochip_symbol_offset (rtx operand) picochip_symbol_offset (rtx operand)
...@@ -4395,11 +4544,11 @@ picochip_check_conditional_copy (rtx * operands) ...@@ -4395,11 +4544,11 @@ picochip_check_conditional_copy (rtx * operands)
handled using logical operations (e.g., SIreg != 0 when low || handled using logical operations (e.g., SIreg != 0 when low ||
high). Need to find test cases to provoke this though (fixunssfdi high). Need to find test cases to provoke this though (fixunssfdi
in libgcc does, but is complicated). */ in libgcc does, but is complicated). */
if (GET_MODE (branch_op_0) != HImode || if (register_operand(branch_op_0, GET_MODE(branch_op_0)) &&
!(register_operand (branch_op_0, GET_MODE (branch_op_0)))) GET_MODE(branch_op_0) != HImode)
return 0; return 0;
if (GET_MODE (branch_op_1) != HImode || if (register_operand(branch_op_1, GET_MODE(branch_op_1)) &&
!(picochip_comparison_operand (branch_op_1, GET_MODE (branch_op_1)))) GET_MODE(branch_op_1) != HImode)
return 0; return 0;
return 1; return 1;
......
...@@ -495,7 +495,10 @@ extern const enum reg_class picochip_regno_reg_class[FIRST_PSEUDO_REGISTER]; ...@@ -495,7 +495,10 @@ extern const enum reg_class picochip_regno_reg_class[FIRST_PSEUDO_REGISTER];
correct code is generated. */ correct code is generated. */
#define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN) \ #define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN) \
if (picochip_symbol_offset(X)) { X = gen_rtx_CONST(MODE, X); } do { \
if (picochip_legitimize_reload_address(&X,MODE,OPNUM,TYPE,IND_LEVELS)) \
goto WIN; \
} while(0); \
/* Nonzero if the constant rtx X is a legitimate general operand. X /* Nonzero if the constant rtx X is a legitimate general operand. X
satisfies CONSTANT_P. */ satisfies CONSTANT_P. */
......
...@@ -590,6 +590,23 @@ ...@@ -590,6 +590,23 @@
(set_attr "length" "2,2,4") (set_attr "length" "2,2,4")
]) ])
;; This pattern was added to match the previous pattern. When doing if-convert
;; the pattern generated using movhicc does not have a eq:CC but only a eq for
;; operator. If this pattern were not to be there, Gcc decides not to use
;; movhicc at all. Whereas, in Gcc 4.4, it seems to be cleverer.
(define_insn "*supported_compare1"
[(set (reg:CC CC_REGNUM)
(match_operator 0 "picochip_supported_comparison_operator"
[(match_operand:HI 1 "register_operand" "r,r,r")
(match_operand:HI 2 "picochip_comparison_operand" "r,J,i")]))]
""
"* return picochip_output_compare(operands);"
[; Must be picoAlu because it sets the condition flags.
(set_attr "type" "picoAlu,picoAlu,picoAlu")
(set_attr "longConstant" "false,false,true")
(set_attr "length" "2,2,4")
])
(define_insn "*compare" (define_insn "*compare"
[(set (reg:CC CC_REGNUM) [(set (reg:CC CC_REGNUM)
(match_operator:CC 0 "comparison_operator" (match_operator:CC 0 "comparison_operator"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment