Commit 4eddc42b by Oleg Endo

re PR target/54089 ([SH] Refactor shift patterns)

	PR target/54089
	* config/sh/predicates.md (arith_reg_or_t_reg_operand): New predicate.
	* config/sh/sh.md (*rotcr): Use arith_reg_or_t_reg_operand predicate.
	Handle the case where one of the operands is T_REG.
	Add new pattern to handle MSB extraction.

	PR target/54089
	* gcc.target/sh/pr54089-1.c (test_11, test_12, test_13, test_14): New
	functions.

From-SVN: r191490
parent 8b75f550
2012-09-19 Oleg Endo <olegendo@gcc.gnu.org>
PR target/54089
* config/sh/predicates.md (arith_reg_or_t_reg_operand): New predicate.
* config/sh/sh.md (*rotcr): Use arith_reg_or_t_reg_operand predicate.
Handle the case where one of the operands is T_REG.
Add new pattern to handle MSB extraction.
2012-09-19 Oleg Endo <olegendo@gcc.gnu.org>
PR target/54236
* config/sh/sh.md (*addc): Add pattern to handle one bit left shifts.
......
......@@ -1028,3 +1028,8 @@
return 0;
}
})
;; Returns true of OP is arith_reg_operand or t_reg_operand.
(define_predicate "arith_reg_or_t_reg_operand"
(ior (match_operand 0 "arith_reg_operand")
(match_operand 0 "t_reg_operand")))
......@@ -3940,7 +3940,7 @@ label:
[(set (match_operand:SI 0 "arith_reg_dest")
(ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand")
(match_operand:SI 2 "const_int_operand"))
(ashift:SI (match_operand:SI 3 "t_reg_operand")
(ashift:SI (match_operand:SI 3 "arith_reg_or_t_reg_operand")
(const_int 31))))
(clobber (reg:SI T_REG))]
"TARGET_SH1"
......@@ -3992,6 +3992,17 @@ label:
emit_insn (gen_cmpgtsi_t (tmp_t_reg, const0_rtx));
}
/* For the rotcr insn to work, operands[3] must be in T_REG.
If it is not we can get it there by shifting it right one bit.
In this case T_REG is not an input for this insn, thus we don't have to
pay attention as of where to insert the shlr insn. */
if (! t_reg_operand (operands[3], SImode))
{
/* We don't care about the shifted result here, only the T_REG. */
emit_insn (gen_shlr (gen_reg_rtx (SImode), operands[3]));
operands[3] = get_t_reg_rtx ();
}
emit_insn (gen_rotcr (operands[0], operands[1], operands[3]));
DONE;
})
......@@ -4011,6 +4022,24 @@ label:
(set (reg:SI T_REG)
(and:SI (match_dup 0) (const_int 1)))])])
(define_insn_and_split "*rotcr"
[(set (match_operand:SI 0 "arith_reg_dest")
(ior:SI (and:SI (match_operand:SI 1 "arith_reg_operand")
(const_int -2147483648)) ;; 0xffffffff80000000
(lshiftrt:SI (match_operand:SI 2 "arith_reg_operand")
(const_int 1))))
(clobber (reg:SI T_REG))]
"TARGET_SH1"
"#"
"&& can_create_pseudo_p ()"
[(const_int 0)]
{
rtx tmp = gen_reg_rtx (SImode);
emit_insn (gen_shll (tmp, operands[1]));
emit_insn (gen_rotcr (operands[0], operands[2], get_t_reg_rtx ()));
DONE;
})
;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;; SImode shift left
......
2012-09-19 Oleg Endo <olegendo@gcc.gnu.org>
PR target/54089
* gcc.target/sh/pr54089-1.c (test_11, test_12, test_13, test_14): New
functions.
2012-09-19 Oleg Endo <olegendo@gcc.gnu.org>
PR target/54236
* gcc.target/sh/pr54236-1.c (test_08): Add one bit left shift case.
......
......@@ -2,7 +2,8 @@
/* { dg-do compile { target "sh*-*-*" } } */
/* { dg-options "-O1" } */
/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */
/* { dg-final { scan-assembler-times "rotcr" 11 } } */
/* { dg-final { scan-assembler-times "rotcr" 15 } } */
/* { dg-final { scan-assembler-times "shll\t" 1 } } */
typedef char bool;
......@@ -81,3 +82,30 @@ test_10 (int a, int b)
bool r = a == b;
return r << 31;
}
unsigned int
test_11 (unsigned int a, int b)
{
/* 1x shlr, 1x rotcr */
return (a >> 1) | (b << 31);
}
unsigned int
test_12 (unsigned int a, int b)
{
return (a >> 2) | (b << 31);
}
unsigned int
test_13 (unsigned int a, int b)
{
return (a >> 3) | (b << 31);
}
unsigned int
test_14 (unsigned int a, int b)
{
/* 1x shll, 1x rotcr */
bool r = b < 0;
return ((a >> 1) | (r << 31));
}
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