mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-30 21:41:16 +08:00
re PR bootstrap/49486 (Bootstrap failure)
PR target/49486 * config/sh/sh.md (negdi2): Move expansion into split to allow more combination options. Add T_REG clobber. (abssi2): New expander. (*negdi2, *abssi2, *negabssi2): New insns. (cneg): Change from insn to insn_and_split. Rename to negsi_cond. Add alternative for non-SH4. * gcc.target/sh/pr49468-si.c: New. From-SVN: r179320
This commit is contained in:
parent
8c850a5a7f
commit
39f2bcb5e1
@ -1,3 +1,13 @@
|
||||
2011-09-28 Oleg Endo <oleg.endo@t-online.de>
|
||||
|
||||
PR target/49486
|
||||
* config/sh/sh.md (negdi2): Move expansion into split to
|
||||
allow more combination options. Add T_REG clobber.
|
||||
(abssi2): New expander.
|
||||
(*negdi2, *abssi2, *negabssi2): New insns.
|
||||
(cneg): Change from insn to insn_and_split. Rename to
|
||||
negsi_cond. Add alternative for non-SH4.
|
||||
|
||||
2011-09-28 Richard Sandiford <richard.sandiford@linaro.org>
|
||||
|
||||
* config/arm/neon.md (neon_move_lo_quad_<mode>): Delete.
|
||||
|
@ -4282,28 +4282,39 @@ label:
|
||||
"sub r63, %1, %0"
|
||||
[(set_attr "type" "arith_media")])
|
||||
|
||||
|
||||
|
||||
;; Don't expand immediately because otherwise neg:DI (abs:DI) will not be
|
||||
;; combined.
|
||||
(define_expand "negdi2"
|
||||
[(set (match_operand:DI 0 "arith_reg_operand" "")
|
||||
(neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
|
||||
[(set (match_operand:DI 0 "arith_reg_dest" "")
|
||||
(neg:DI (match_operand:DI 1 "arith_reg_operand" "")))
|
||||
(clobber (reg:SI T_REG))]
|
||||
""
|
||||
"")
|
||||
|
||||
(define_insn_and_split "*negdi2"
|
||||
[(set (match_operand:DI 0 "arith_reg_dest" "=r")
|
||||
(neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
|
||||
"TARGET_SH1"
|
||||
"#"
|
||||
"TARGET_SH1"
|
||||
[(const_int 0)]
|
||||
"
|
||||
{
|
||||
if (TARGET_SH1)
|
||||
{
|
||||
int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
|
||||
int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
|
||||
int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
|
||||
int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
|
||||
|
||||
rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
|
||||
rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
|
||||
rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
|
||||
rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
|
||||
|
||||
rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
|
||||
rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
|
||||
rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
|
||||
rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
|
||||
|
||||
emit_insn (gen_clrt ());
|
||||
emit_insn (gen_negc (low_dst, low_src));
|
||||
emit_insn (gen_negc (high_dst, high_src));
|
||||
DONE;
|
||||
}
|
||||
emit_insn (gen_clrt ());
|
||||
emit_insn (gen_negc (low_dst, low_src));
|
||||
emit_insn (gen_negc (high_dst, high_src));
|
||||
DONE;
|
||||
}")
|
||||
|
||||
(define_insn "negsi2"
|
||||
@ -4326,27 +4337,77 @@ label:
|
||||
(const_int -1)))]
|
||||
"TARGET_SHMEDIA" "")
|
||||
|
||||
/* The SH4 202 can do zero-offset branches without pipeline stalls.
|
||||
This can be used as some kind of conditional execution, which is useful
|
||||
for abs. */
|
||||
(define_split
|
||||
(define_expand "abssi2"
|
||||
[(set (match_operand:SI 0 "arith_reg_dest" "")
|
||||
(plus:SI (xor:SI (neg:SI (reg:SI T_REG))
|
||||
(match_operand:SI 1 "arith_reg_operand" ""))
|
||||
(reg:SI T_REG)))]
|
||||
"TARGET_HARD_SH4"
|
||||
[(const_int 0)]
|
||||
"emit_insn (gen_movsi_i (operands[0], operands[1]));
|
||||
emit_insn (gen_cneg (operands[0], operands[0], operands[0]));
|
||||
DONE;")
|
||||
(abs:SI (match_operand:SI 1 "arith_reg_operand" "")))
|
||||
(clobber (reg:SI T_REG))]
|
||||
""
|
||||
"")
|
||||
|
||||
(define_insn "cneg"
|
||||
(define_insn_and_split "*abssi2"
|
||||
[(set (match_operand:SI 0 "arith_reg_dest" "=r")
|
||||
(if_then_else:SI (eq:SI (reg:SI T_REG) (const_int 0))
|
||||
(match_operand:SI 1 "arith_reg_operand" "0")
|
||||
(neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
|
||||
(abs:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
|
||||
"TARGET_SH1"
|
||||
"#"
|
||||
"TARGET_SH1"
|
||||
[(const_int 0)]
|
||||
"
|
||||
{
|
||||
emit_insn (gen_cmpgesi_t (operands[1], const0_rtx));
|
||||
emit_insn (gen_negsi_cond (operands[0], operands[1], operands[1],
|
||||
const1_rtx));
|
||||
DONE;
|
||||
}")
|
||||
|
||||
(define_insn_and_split "*negabssi2"
|
||||
[(set (match_operand:SI 0 "arith_reg_dest" "=r")
|
||||
(neg:SI (abs:SI (match_operand:SI 1 "arith_reg_operand" "r"))))]
|
||||
"TARGET_SH1"
|
||||
"#"
|
||||
"TARGET_SH1"
|
||||
[(const_int 0)]
|
||||
"
|
||||
{
|
||||
emit_insn (gen_cmpgesi_t (operands[1], const0_rtx));
|
||||
emit_insn (gen_negsi_cond (operands[0], operands[1], operands[1],
|
||||
const0_rtx));
|
||||
DONE;
|
||||
}")
|
||||
|
||||
|
||||
;; The SH4 202 can do zero-offset branches without pipeline stalls.
|
||||
;; This can be used as some kind of conditional execution, which is useful
|
||||
;; for abs.
|
||||
;; Actually the instruction scheduling should decide whether to use a
|
||||
;; zero-offset branch or not for any generic case involving a single
|
||||
;; instruction on SH4 202.
|
||||
|
||||
(define_insn_and_split "negsi_cond"
|
||||
[(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
|
||||
(if_then_else:SI (eq:SI (reg:SI T_REG)
|
||||
(match_operand:SI 3 "const_int_operand" "M,N"))
|
||||
(match_operand:SI 1 "arith_reg_operand" "0,0")
|
||||
(neg:SI (match_operand:SI 2 "arith_reg_operand" "r,r"))))]
|
||||
"TARGET_HARD_SH4"
|
||||
"bf 0f\;neg %2,%0\\n0:"
|
||||
"@
|
||||
bt\\t0f\;neg\\t%2,%0\\n0:
|
||||
bf\\t0f\;neg\\t%2,%0\\n0:"
|
||||
"!TARGET_HARD_SH4"
|
||||
[(const_int 0)]
|
||||
"
|
||||
{
|
||||
rtx skip_neg_label = gen_label_rtx ();
|
||||
|
||||
emit_insn (gen_movsi (operands[0], operands[1]));
|
||||
|
||||
emit_jump_insn (INTVAL (operands[3])
|
||||
? gen_branch_true (skip_neg_label)
|
||||
: gen_branch_false (skip_neg_label));
|
||||
|
||||
emit_label_after (skip_neg_label,
|
||||
emit_insn (gen_negsi2 (operands[0], operands[1])));
|
||||
DONE;
|
||||
}"
|
||||
[(set_attr "type" "arith") ;; poor approximation
|
||||
(set_attr "length" "4")])
|
||||
|
||||
|
@ -1,3 +1,8 @@
|
||||
2011-09-28 Oleg Endo <oleg.endo@t-online.de>
|
||||
|
||||
PR target/49486
|
||||
* gcc.target/sh/pr49468-si.c: New.
|
||||
|
||||
2011-09-28 Tom de Vries <tom@codesourcery.com>
|
||||
|
||||
PR testsuite/50485
|
||||
|
22
gcc/testsuite/gcc.target/sh/pr49468-si.c
Normal file
22
gcc/testsuite/gcc.target/sh/pr49468-si.c
Normal file
@ -0,0 +1,22 @@
|
||||
/* Check that 32 bit integer abs is generated as neg instruction and
|
||||
conditional branch instead of default branch-free code. */
|
||||
/* { dg-do compile { target "sh*-*-*" } } */
|
||||
/* { dg-options "-O1" } */
|
||||
/* { dg-final { scan-assembler-times "neg" 2 } } */
|
||||
|
||||
|
||||
/* Normal integer absolute value. */
|
||||
int
|
||||
abs_0 (int i)
|
||||
{
|
||||
return (i < 0) ? -i : i;
|
||||
}
|
||||
|
||||
/* Negated integer absolute value.
|
||||
The generated code should be the same, except that the branch
|
||||
condition is inverted. */
|
||||
int
|
||||
abs_1 (int i)
|
||||
{
|
||||
return (i > 0) ? -i : i;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user