re PR bootstrap/49486 (Bootstrap failure)
authorOleg Endo <olegendo@gcc.gnu.org>
Fri, 2 Mar 2012 21:21:13 +0000 (21:21 +0000)
committerOleg Endo <olegendo@gcc.gnu.org>
Fri, 2 Mar 2012 21:21:13 +0000 (21:21 +0000)
PR target/49486
* config/sh/sh.md (negdi2): Add TARGET_SH1 condition.
(absdi2): New expander.
(*absdi2, *negabsdi2, negdi_cond): New insns and splits.
* gcc.target/sh/pr49468-si.c: Skip unsupported test for SH64.
* gcc.target/sh/pr49468-di.c: New.

From-SVN: r184829

gcc/ChangeLog
gcc/config/sh/sh.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/sh/pr49468-di.c [new file with mode: 0644]
gcc/testsuite/gcc.target/sh/pr49468-si.c

index c0242a9e62b4b603c1b801a5e113d2ed45025b7f..eabe45f2dfd468c360e03eb96eac244f53df6590 100644 (file)
@@ -1,3 +1,10 @@
+2012-03-02  Oleg Endo  <olegendo@gcc.gnu.org>
+
+       PR target/49486
+       * config/sh/sh.md (negdi2): Add TARGET_SH1 condition.
+       (absdi2): New expander.
+       (*absdi2, *negabsdi2, negdi_cond): New insns and splits.
+
 2012-03-02  Oleg Endo  <olegendo@gcc.gnu.org>
 
        * config/sh/sync.md (atomic_exchange<mode>): New expander.
index b356584d55140dc799cd1372d41e231e51d759fb..56a0f3c5acf0732cadd084c9a2802c63e7d47df7 100644 (file)
@@ -4411,7 +4411,7 @@ label:
   [(set (match_operand:DI 0 "arith_reg_dest" "")
        (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))
    (clobber (reg:SI T_REG))]
-  ""
+  "TARGET_SH1"
   "")
 
 (define_insn_and_split "*negdi2"
@@ -4531,6 +4531,82 @@ label:
   [(set_attr "type" "arith") ;; poor approximation
    (set_attr "length" "4")])
 
+(define_expand "absdi2"
+  [(set (match_operand:DI 0 "arith_reg_dest" "")
+       (abs:DI (match_operand:DI 1 "arith_reg_operand" "")))
+   (clobber (reg:SI T_REG))]
+  "TARGET_SH1"
+  "")
+
+(define_insn_and_split "*absdi2"
+  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
+       (abs:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
+  "TARGET_SH1"
+  "#"
+  "&& reload_completed"
+  [(const_int 0)]
+{
+  int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
+  rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
+  emit_insn (gen_cmpgesi_t (high_src, const0_rtx));
+  emit_insn (gen_negdi_cond (operands[0], operands[1], operands[1],
+                            const1_rtx));
+  DONE;
+})
+
+(define_insn_and_split "*negabsdi2"
+  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
+       (neg:DI (abs:DI (match_operand:DI 1 "arith_reg_operand" "r"))))]
+  "TARGET_SH1"
+  "#"
+  "&& reload_completed"
+  [(const_int 0)]
+{
+  int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
+  rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
+
+  emit_insn (gen_cmpgesi_t (high_src, const0_rtx));
+  emit_insn (gen_negdi_cond (operands[0], operands[1], operands[1],
+                            const0_rtx));
+  DONE;
+})
+
+(define_insn_and_split "negdi_cond"
+  [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
+       (if_then_else:DI (eq:SI (reg:SI T_REG)
+                               (match_operand:SI 3 "const_int_operand" "M,N"))
+        (match_operand:DI 1 "arith_reg_operand" "r,r")
+        (neg:DI (match_operand:DI 2 "arith_reg_operand" "1,1"))))]
+  "TARGET_SH1"
+  "#"
+  "TARGET_SH1"
+  [(const_int 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_dst = operand_subword (operands[0], low_word, 1, DImode);
+  rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
+
+  rtx skip_neg_label = gen_label_rtx ();
+
+  emit_insn (gen_movsi (low_dst, low_src));
+  emit_insn (gen_movsi (high_dst, high_src));
+
+  emit_jump_insn (INTVAL (operands[3]) 
+                 ? gen_branch_true (skip_neg_label)
+                 : gen_branch_false (skip_neg_label));
+
+  if (!INTVAL (operands[3]))
+    emit_insn (gen_clrt ());
+
+  emit_insn (gen_negc (low_dst, low_src));
+  emit_label_after (skip_neg_label, emit_insn (gen_negc (high_dst, high_src)));
+  DONE;
+})
 \f
 ;; -------------------------------------------------------------------------
 ;; Zero extension instructions
index 4868f338558f494651e91d96940ddb76ed9cb5a4..9c4fc1acc600b399868aa95ef19f6efed49a9c02 100644 (file)
@@ -1,3 +1,9 @@
+2012-03-02  Oleg Endo  <olegendo@gcc.gnu.org>
+
+       PR target/49486
+       * gcc.target/sh/pr49468-si.c: Skip unsupported test for SH64.
+       * gcc.target/sh/pr49468-di.c: New.
+
 2012-03-02  Maxim Kuvyrkov  <maxim@codesourcery.com>
 
        * gcc.dg/graphite/pr50561.c: Update.
diff --git a/gcc/testsuite/gcc.target/sh/pr49468-di.c b/gcc/testsuite/gcc.target/sh/pr49468-di.c
new file mode 100644 (file)
index 0000000..86fe21d
--- /dev/null
@@ -0,0 +1,23 @@
+/* Check that 64 bit integer abs is generated as negc instruction pairs
+   and conditional branch instead of default branch-free code.  */
+/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } }  */
+/* { dg-do compile { target "sh*-*-*" } } */
+/* { dg-options "-O1" } */
+/* { dg-final { scan-assembler-times "negc" 4 } } */
+
+
+/* Normal integer absolute value.  */
+long long
+abs_0 (long long i)
+{
+  return (i < 0) ? -i : i;
+}
+
+/*  Negated integer absolute value.
+    The generated code should be the same, except that the branch 
+    condition is inverted.  */
+long long
+abs_1 (long long i)
+{
+  return (i > 0) ? -i : i;
+}
index 69fbe230efaf970a263f969103eed1ea78573f6a..e581b2a1f6ea6f55c01ba346229aebe138a4d80d 100644 (file)
@@ -1,5 +1,6 @@
 /* Check that 32 bit integer abs is generated as neg instruction and
    conditional branch instead of default branch-free code.  */
+/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } }  */
 /* { dg-do compile { target "sh*-*-*" } } */
 /* { dg-options "-O1" } */
 /* { dg-final { scan-assembler-times "neg" 2 } } */