bfin.md (<optab>di3): Now a define_expand which expands logical operations piecewise.
authorBernd Schmidt <bernd.schmidt@analog.com>
Fri, 4 May 2007 11:00:00 +0000 (11:00 +0000)
committerBernd Schmidt <bernds@gcc.gnu.org>
Fri, 4 May 2007 11:00:00 +0000 (11:00 +0000)
* config/bfin/bfin.md (<optab>di3): Now a define_expand which expands
logical operations piecewise.
(<optab>di_zesidi_di, <optab>di_sesidi_di, negdi2, one_cmpldi2,
zero_extendsidi2, subdi_di_zesidi, subdi_zesidi_di, subdi_di_sesidi,
subdi_sesidi_di): Delete.
(add_with_carry): Produce carry in CC instead of a DREG to shorten
the generated sequence.  Allow three-reg add in constraints.  Rewrite
the rtl expression for carry to avoid zero_extend of a constant.
(sub_with_carry): New pattern.
(adddi3, subdi3): Change into define_expand.  For subtract, generate a
different sequence not involving jumps.
(notbi): Now a named pattern.

From-SVN: r124414

gcc/ChangeLog
gcc/config/bfin/bfin.md

index 5c028131169c52f8b58e157d874325059b2d97f4..85404e0d12562d3172db03b1cdcc08b75fc45f24 100644 (file)
@@ -1,3 +1,18 @@
+2007-04-18  Bernd Schmidt  <bernd.schmidt@analog.com>
+
+       * config/bfin/bfin.md (<optab>di3): Now a define_expand which expands
+       logical operations piecewise.
+       (<optab>di_zesidi_di, <optab>di_sesidi_di, negdi2, one_cmpldi2,
+       zero_extendsidi2, subdi_di_zesidi, subdi_zesidi_di, subdi_di_sesidi,
+       subdi_sesidi_di): Delete.
+       (add_with_carry): Produce carry in CC instead of a DREG to shorten
+       the generated sequence.  Allow three-reg add in constraints.  Rewrite
+       the rtl expression for carry to avoid zero_extend of a constant.
+       (sub_with_carry): New pattern.
+       (adddi3, subdi3): Change into define_expand.  For subtract, generate a
+       different sequence not involving jumps.
+       (notbi): Now a named pattern.
+
 2007-05-04  Bradley Lucier  <lucier@math.purdue.edu>
 
        * doc/invoke.texi (i386 and x86-64 Options) [-mpc32, -mpc64, -mpc80]:
index 217c26d7d159dad7c5a3c57e083b73518a523a19..7b238c64982267aee2e3b88bac7beafd69672115 100644 (file)
                               (ior "%H1")
                               (xor "%H1")])
 
-(define_insn "<optab>di3"
+;; Keep this pattern around to avoid generating NO_CONFLICT blocks.
+(define_expand "<optab>di3"
   [(set (match_operand:DI 0 "register_operand" "=d")
         (any_logical:DI (match_operand:DI 1 "register_operand" "0")
-                       (match_operand:DI 2 "register_operand" "d")))]
+                       (match_operand:DI 2 "general_operand" "d")))]
   ""
-  "%0 = %1 <op> %2;\\n\\t%H0 = %H1 <op> %H2;"
-  [(set_attr "length" "4")
-   (set_attr "seq_insns" "multi")])
-
-(define_insn "*<optab>di_zesidi_di"
-  [(set (match_operand:DI 0 "register_operand" "=d")
-        (any_logical:DI (zero_extend:DI
-                        (match_operand:SI 2 "register_operand" "d"))
-                       (match_operand:DI 1 "register_operand" "d")))]
-  ""
-  "%0 = %1 <op>  %2;\\n\\t%H0 = <high_result>;"
-  [(set_attr "length" "4")
-   (set_attr "seq_insns" "multi")])
-
-(define_insn "*<optab>di_sesdi_di"
-  [(set (match_operand:DI 0 "register_operand" "=d")
-        (any_logical:DI (sign_extend:DI
-                        (match_operand:SI 2 "register_operand" "d"))
-                       (match_operand:DI 1 "register_operand" "0")))
-   (clobber (match_scratch:SI 3 "=&d"))]
-  ""
-  "%0 = %1 <op> %2;\\n\\t%3 = %2;\\n\\t%3 >>>= 31;\\n\\t%H0 = %H1 <op> %3;"
-  [(set_attr "length" "8")
-   (set_attr "seq_insns" "multi")])
-
-(define_insn "negdi2"
-  [(set (match_operand:DI 0 "register_operand" "=d")
-        (neg:DI (match_operand:DI 1 "register_operand" "d")))
-   (clobber (match_scratch:SI 2 "=&d"))
-   (clobber (reg:CC REG_CC))]
-  ""
-  "%2 = 0; %2 = %2 - %1; cc = ac0; cc = !cc; %2 = cc;\\n\\t%0 = -%1; %H0 = -%H1; %H0 = %H0 - %2;"
-  [(set_attr "length" "16")
-   (set_attr "seq_insns" "multi")])
-
-(define_insn "one_cmpldi2"
-  [(set (match_operand:DI 0 "register_operand" "=d")
-        (not:DI (match_operand:DI 1 "register_operand" "d")))]
-  ""
-  "%0 = ~%1;\\n\\t%H0 = ~%H1;"
-  [(set_attr "length" "4")
-   (set_attr "seq_insns" "multi")])
-
-;; DImode zero and sign extend patterns
-
-(define_insn_and_split "zero_extendsidi2"
-  [(set (match_operand:DI 0 "register_operand" "=d")
-        (zero_extend:DI (match_operand:SI 1 "register_operand" "d")))]
-  ""
-  "#"
-  "reload_completed"
-  [(set (match_dup 3) (const_int 0))]
 {
-  split_di (operands, 1, operands + 2, operands + 3);
-  if (REGNO (operands[0]) != REGNO (operands[1]))
-    emit_move_insn (operands[2], operands[1]);
+  rtx hi_half[3], lo_half[3];
+  enum insn_code icode = CODE_FOR_<optab>si3;
+  if (!reg_overlap_mentioned_p (operands[0], operands[1])
+      && !reg_overlap_mentioned_p (operands[0], operands[2]))
+    emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[0]));
+  split_di (operands, 3, lo_half, hi_half);
+  if (!(*insn_data[icode].operand[2].predicate) (lo_half[2], SImode))
+    lo_half[2] = force_reg (SImode, lo_half[2]);
+  emit_insn (GEN_FCN (icode) (lo_half[0], lo_half[1], lo_half[2]));
+  if (!(*insn_data[icode].operand[2].predicate) (hi_half[2], SImode))
+    hi_half[2] = force_reg (SImode, hi_half[2]);
+  emit_insn (GEN_FCN (icode) (hi_half[0], hi_half[1], hi_half[2]));
+  DONE;
 })
 
 (define_insn "zero_extendqidi2"
 
 (define_insn "add_with_carry"
   [(set (match_operand:SI 0 "register_operand" "=d,d")
-        (plus:SI (match_operand:SI 1 "register_operand" "%0,0")
+        (plus:SI (match_operand:SI 1 "register_operand" "%0,d")
                  (match_operand:SI 2 "nonmemory_operand" "Ks7,d")))
-   (set (match_operand:SI 3 "register_operand" "=d,d")
-       (truncate:SI
-        (lshiftrt:DI (plus:DI (zero_extend:DI (match_dup 1))
-                              (zero_extend:DI (match_dup 2)))
-                     (const_int 32))))
-   (clobber (reg:CC 34))]
+   (set (match_operand:BI 3 "register_operand" "=C,C")
+       (ltu:BI (not:SI (match_dup 1)) (match_dup 2)))]
   ""
   "@
-   %0 += %2; cc = ac0; %3 = cc;
-   %0 = %0 + %2; cc = ac0; %3 = cc;"
+   %0 += %2; cc = ac0;
+   %0 = %1 + %2; cc = ac0;"
   [(set_attr "type" "alu0")
-   (set_attr "length" "6")
+   (set_attr "length" "4")
    (set_attr "seq_insns" "multi")])
 
-(define_insn "adddi3"
-  [(set (match_operand:DI 0 "register_operand" "=&d,&d,&d")
-        (plus:DI (match_operand:DI 1 "register_operand" "%0,0,0")
-                 (match_operand:DI 2 "nonmemory_operand" "Kn7,Ks7,d")))
-   (clobber (match_scratch:SI 3 "=&d,&d,&d"))
-   (clobber (reg:CC 34))]
+(define_insn "sub_with_carry"
+  [(set (match_operand:SI 0 "register_operand" "=d")
+        (minus:SI (match_operand:SI 1 "register_operand" "%d")
+                 (match_operand:SI 2 "nonmemory_operand" "d")))
+   (set (match_operand:BI 3 "register_operand" "=C")
+       (leu:BI (match_dup 2) (match_dup 1)))]
   ""
-  "@
-   %0 += %2; cc = ac0; %3 = cc; %H0 += -1; %H0 = %H0 + %3;
-   %0 += %2; cc = ac0; %3 = cc; %H0 = %H0 + %3;
-   %0 = %0 + %2; cc = ac0; %3 = cc; %H0 = %H0 + %H2; %H0 = %H0 + %3;"
+  "%0 = %1 - %2; cc = ac0;"
   [(set_attr "type" "alu0")
-   (set_attr "length" "10,8,10")
-   (set_attr "seq_insns" "multi,multi,multi")])
-
-(define_insn "subdi3"
-  [(set (match_operand:DI 0 "register_operand" "=&d")
-        (minus:DI (match_operand:DI 1 "register_operand" "0")
-                  (match_operand:DI 2 "register_operand" "d")))
-   (clobber (reg:CC 34))]
-  ""
-  "%0 = %1-%2;\\n\\tcc = ac0;\\n\\t%H0 = %H1-%H2;\\n\\tif cc jump 1f;\\n\\t%H0 += -1;\\n\\t1:"
-  [(set_attr "length" "10")
-   (set_attr "seq_insns" "multi")])
-
-(define_insn "*subdi_di_zesidi"
-  [(set (match_operand:DI 0 "register_operand" "=d")
-        (minus:DI (match_operand:DI 1 "register_operand" "0")
-                  (zero_extend:DI
-                  (match_operand:SI 2 "register_operand" "d"))))
-   (clobber (match_scratch:SI 3 "=&d"))
-   (clobber (reg:CC 34))]
-  ""
-  "%0 = %1 - %2;\\n\\tcc = ac0;\\n\\tcc = ! cc;\\n\\t%3 = cc;\\n\\t%H0 = %H1 - %3;"
-  [(set_attr "length" "10")
-   (set_attr "seq_insns" "multi")])
-
-(define_insn "*subdi_zesidi_di"
-  [(set (match_operand:DI 0 "register_operand" "=d")
-        (minus:DI (zero_extend:DI
-                  (match_operand:SI 2 "register_operand" "d"))
-                  (match_operand:DI 1 "register_operand" "0")))
-   (clobber (match_scratch:SI 3 "=&d"))
-   (clobber (reg:CC 34))]
-  ""
-  "%0 = %2 - %1;\\n\\tcc = ac0;\\n\\tcc = ! cc;\\n\\t%3 = cc;\\n\\t%3 = -%3;\\n\\t%H0 = %3 - %H1"
-  [(set_attr "length" "12")
+   (set_attr "length" "4")
    (set_attr "seq_insns" "multi")])
 
-(define_insn "*subdi_di_sesidi"
-  [(set (match_operand:DI 0 "register_operand" "=d")
-        (minus:DI (match_operand:DI 1 "register_operand" "0")
-                  (sign_extend:DI
-                  (match_operand:SI 2 "register_operand" "d"))))
-   (clobber (match_scratch:SI 3 "=&d"))
+(define_expand "adddi3"
+  [(set (match_operand:DI 0 "register_operand" "")
+        (plus:DI (match_operand:DI 1 "register_operand" "")
+                 (match_operand:DI 2 "nonmemory_operand" "")))
+   (clobber (match_scratch:SI 3 ""))
    (clobber (reg:CC 34))]
   ""
-  "%0 = %1 - %2;\\n\\tcc = ac0;\\n\\t%3 = %2;\\n\\t%3 >>>= 31;\\n\\t%H0 = %H1 - %3;\\n\\tif cc jump 1f;\\n\\t%H0 += -1;\\n\\t1:"
-  [(set_attr "length" "14")
-   (set_attr "seq_insns" "multi")])
+{
+  rtx xops[8];
+  xops[0] = gen_lowpart (SImode, operands[0]);
+  xops[1] = simplify_gen_subreg (SImode, operands[0], DImode, 4);
+  xops[2] = gen_lowpart (SImode, operands[1]);
+  xops[3] = simplify_gen_subreg (SImode, operands[1], DImode, 4);
+  xops[4] = gen_lowpart (SImode, operands[2]);
+  xops[5] = simplify_gen_subreg (SImode, operands[2], DImode, 4);
+  xops[6] = gen_reg_rtx (SImode);
+  xops[7] = gen_rtx_REG (BImode, REG_CC);
+  if (!register_operand (xops[4], SImode)
+      && (GET_CODE (xops[4]) != CONST_INT
+          || !CONST_OK_FOR_K (INTVAL (xops[4]), "Ks7")))
+    xops[4] = force_reg (SImode, xops[4]);
+  if (!reg_overlap_mentioned_p (operands[0], operands[1])
+      && !reg_overlap_mentioned_p (operands[0], operands[2]))
+    emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[0]));
+  emit_insn (gen_add_with_carry (xops[0], xops[2], xops[4], xops[7]));
+  emit_insn (gen_movbisi (xops[6], xops[7]));
+  if (!register_operand (xops[5], SImode)
+      && (GET_CODE (xops[5]) != CONST_INT
+          || !CONST_OK_FOR_K (INTVAL (xops[5]), "Ks7")))
+    xops[5] = force_reg (SImode, xops[5]);
+  if (xops[5] != const0_rtx)
+    emit_insn (gen_addsi3 (xops[1], xops[3], xops[5]));
+  else
+    emit_move_insn (xops[1], xops[3]);
+  emit_insn (gen_addsi3 (xops[1], xops[1], xops[6]));
+  DONE;
+})
 
-(define_insn "*subdi_sesidi_di"
-  [(set (match_operand:DI 0 "register_operand" "=d")
-        (minus:DI (sign_extend:DI
-                  (match_operand:SI 2 "register_operand" "d"))
-                  (match_operand:DI 1 "register_operand" "0")))
-   (clobber (match_scratch:SI 3 "=&d"))
+(define_expand "subdi3"
+  [(set (match_operand:DI 0 "register_operand" "")
+        (minus:DI (match_operand:DI 1 "register_operand" "")
+                  (match_operand:DI 2 "register_operand" "")))
    (clobber (reg:CC 34))]
   ""
-  "%0 = %2 - %1;\\n\\tcc = ac0;\\n\\t%3 = %2;\\n\\t%3 >>>= 31;\\n\\t%H0 = %3 - %H1;\\n\\tif cc jump 1f;\\n\\t%H0 += -1;\\n\\t1:"
-  [(set_attr "length" "14")
-   (set_attr "seq_insns" "multi")])
+{
+  rtx xops[8];
+  xops[0] = gen_lowpart (SImode, operands[0]);
+  xops[1] = simplify_gen_subreg (SImode, operands[0], DImode, 4);
+  xops[2] = gen_lowpart (SImode, operands[1]);
+  xops[3] = simplify_gen_subreg (SImode, operands[1], DImode, 4);
+  xops[4] = gen_lowpart (SImode, operands[2]);
+  xops[5] = simplify_gen_subreg (SImode, operands[2], DImode, 4);
+  xops[6] = gen_reg_rtx (SImode);
+  xops[7] = gen_rtx_REG (BImode, REG_CC);
+  if (!reg_overlap_mentioned_p (operands[0], operands[1])
+      && !reg_overlap_mentioned_p (operands[0], operands[2]))
+    emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[0]));
+  emit_insn (gen_sub_with_carry (xops[0], xops[2], xops[4], xops[7]));
+  emit_insn (gen_notbi (xops[7], xops[7]));
+  emit_insn (gen_movbisi (xops[6], xops[7]));
+  emit_insn (gen_subsi3 (xops[1], xops[3], xops[5]));
+  emit_insn (gen_subsi3 (xops[1], xops[1], xops[6]));
+  DONE;
+})
 
 ;; Combined shift/add instructions
 
   "%0 = CC;"
   [(set_attr "length" "2")])
 
-(define_insn ""
+(define_insn "notbi"
   [(set (match_operand:BI 0 "register_operand" "=C")
        (eq:BI (match_operand:BI 1 "register_operand" " 0")
               (const_int 0)))]