Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/gnu/dist/gcc/config/sh Sync *{mul, div}*i3 with egcs-current.



details:   https://anonhg.NetBSD.org/src/rev/15e46afde8e2
branches:  trunk
changeset: 486354:15e46afde8e2
user:      msaitoh <msaitoh%NetBSD.org@localhost>
date:      Sat May 20 01:52:52 2000 +0000

description:
Sync *{mul,div}*i3 with egcs-current.
Now we can compile mount_mfs (newfs) with -O2!

diffstat:

 gnu/dist/gcc/config/sh/sh.c  |    2 +
 gnu/dist/gcc/config/sh/sh.md |  257 +++++++++++++++++++++++++++++++-----------
 2 files changed, 191 insertions(+), 68 deletions(-)

diffs (truncated from 414 to 300 lines):

diff -r 4254db270e69 -r 15e46afde8e2 gnu/dist/gcc/config/sh/sh.c
--- a/gnu/dist/gcc/config/sh/sh.c       Sat May 20 00:45:45 2000 +0000
+++ b/gnu/dist/gcc/config/sh/sh.c       Sat May 20 01:52:52 2000 +0000
@@ -132,6 +132,7 @@
   switch (GET_CODE (x))
     {
     case REG:
+    case SUBREG:
       fprintf (stream, "@%s", reg_names[REGNO (x)]);
       break;
 
@@ -148,6 +149,7 @@
            break;
 
          case REG:
+         case SUBREG:
            fprintf (stream, "@(r0,%s)",
                     reg_names[MAX (REGNO (base), REGNO (index))]);
            break;
diff -r 4254db270e69 -r 15e46afde8e2 gnu/dist/gcc/config/sh/sh.md
--- a/gnu/dist/gcc/config/sh/sh.md      Sat May 20 00:45:45 2000 +0000
+++ b/gnu/dist/gcc/config/sh/sh.md      Sat May 20 01:52:52 2000 +0000
@@ -661,7 +661,7 @@
 ;; This reload would clobber the value in r0 we are trying to store.
 ;; If we let reload allocate r0, then this problem can never happen.
 
-(define_insn ""
+(define_insn "udivsi3_i1"
   [(set (match_operand:SI 0 "register_operand" "=z")
        (udiv:SI (reg:SI 4) (reg:SI 5)))
    (clobber (reg:SI 18))
@@ -674,9 +674,9 @@
    (set_attr "needs_delay_slot" "yes")])
 
 (define_expand "udivsi3"
-  [(set (reg:SI 4) (match_operand:SI 1 "general_operand" ""))
+  [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
+   (set (reg:SI 4) (match_operand:SI 1 "general_operand" ""))
    (set (reg:SI 5) (match_operand:SI 2 "general_operand" ""))
-   (set (match_dup 3) (symbol_ref:SI "__udivsi3"))
    (parallel [(set (match_operand:SI 0 "register_operand" "")
                   (udiv:SI (reg:SI 4)
                            (reg:SI 5)))
@@ -685,9 +685,26 @@
              (clobber (reg:SI 4))
              (use (match_dup 3))])]
   ""
-  "operands[3] = gen_reg_rtx(SImode);")
-
-(define_insn ""
+  "
+{
+  rtx first, last;
+
+  operands[3] = gen_reg_rtx(SImode);
+  /* Emit the move of the address to a pseudo outside of the libcall.  */
+  emit_move_insn (operands[3],
+                 gen_rtx_SYMBOL_REF (SImode, \"__udivsi3\"));
+  last = gen_udivsi3_i1 (operands[0], operands[3]);
+  first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
+  emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
+  last = emit_insn (last);
+  /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
+     invariant code motion can move it.  */
+  REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
+  REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
+  DONE;
+}")
+
+(define_insn "divsi3_i1"
   [(set (match_operand:SI 0 "register_operand" "=z")
        (div:SI (reg:SI 4) (reg:SI 5)))
    (clobber (reg:SI 18))
@@ -702,9 +719,9 @@
    (set_attr "needs_delay_slot" "yes")])
 
 (define_expand "divsi3"
-  [(set (reg:SI 4) (match_operand:SI 1 "general_operand" ""))
+  [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
+   (set (reg:SI 4) (match_operand:SI 1 "general_operand" ""))
    (set (reg:SI 5) (match_operand:SI 2 "general_operand" ""))
-   (set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
    (parallel [(set (match_operand:SI 0 "register_operand" "")
                   (div:SI (reg:SI 4)
                           (reg:SI 5)))
@@ -715,13 +732,29 @@
              (clobber (reg:SI 3))
              (use (match_dup 3))])]
   ""
-  "operands[3] = gen_reg_rtx(SImode);")
+  "
+{
+  rtx first, last;
+
+  operands[3] = gen_reg_rtx(SImode);
+  /* Emit the move of the address to a pseudo outside of the libcall.  */
+  emit_move_insn (operands[3], gen_rtx_SYMBOL_REF (SImode, \"__sdivsi3\"));
+  last = gen_divsi3_i1 (operands[0], operands[3]);
+  first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
+  emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
+  last = emit_insn (last);
+  /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
+     invariant code motion can move it.  */
+  REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
+  REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
+  DONE;
+}")
 
 ;; -------------------------------------------------------------------------
 ;; Multiplication instructions
 ;; -------------------------------------------------------------------------
 
-(define_insn ""
+(define_insn "umulhisi3_i"
   [(set (reg:SI 21)
        (mult:SI (zero_extend:SI (match_operand:HI 0 "arith_reg_operand" "r"))
                 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r"))))]
@@ -729,7 +762,7 @@
   "mulu        %1,%0"
   [(set_attr "type" "smpy")])
 
-(define_insn ""
+(define_insn "mulhisi3_i"
   [(set (reg:SI 21)
        (mult:SI (sign_extend:SI
                  (match_operand:HI 0 "arith_reg_operand" "r"))
@@ -748,7 +781,18 @@
    (set (match_operand:SI 0 "arith_reg_operand" "")
        (reg:SI 21))]
   ""
-  "")
+  "
+{
+  rtx first, last;
+
+  first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
+  last = emit_move_insn (operands[0], gen_rtx_REG (SImode, 21));
+  /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
+     invariant code motion can move it.  */
+  REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
+  REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
+  DONE;
+}")
 
 (define_expand "umulhisi3"
   [(set (reg:SI 21)
@@ -759,7 +803,18 @@
    (set (match_operand:SI 0 "arith_reg_operand" "")
        (reg:SI 21))]
   ""
-  "")
+  "
+{
+  rtx first, last;
+
+  first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
+  last = emit_move_insn (operands[0], gen_rtx_REG (SImode, 21));
+  /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
+     invariant code motion can move it.  */
+  REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
+  REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
+  DONE;
+}")
 
 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
 ;; a call to a routine which clobbers known registers.
@@ -782,7 +837,6 @@
 (define_expand "mulsi3_call"
   [(set (reg:SI 4) (match_operand:SI 1 "general_operand" ""))
    (set (reg:SI 5) (match_operand:SI 2 "general_operand" ""))
-   (set (match_dup 3) (symbol_ref:SI "__mulsi3"))
    (parallel[(set (match_operand:SI 0 "register_operand" "")
                  (mult:SI (reg:SI 4)
                           (reg:SI 5)))
@@ -792,9 +846,9 @@
             (clobber (reg:SI 3))
             (clobber (reg:SI 2))
             (clobber (reg:SI 1))
-            (use (match_dup 3))])]
+            (use (match_operand:SI 3 "register_operand" ""))])]
   ""
-  "operands[3] = gen_reg_rtx(SImode);")
+  "")
 
 (define_insn "mul_l"
   [(set (reg:SI 21)
@@ -813,82 +867,120 @@
   ""
   "
 {
+  rtx first, last;
+
   if (!TARGET_SH2)
     {
-      FAIL;
-      /* ??? Does this give worse or better code?  */
-      emit_insn (gen_mulsi3_call (operands[0], operands[1], operands[2]));
-      DONE;
+      /* The address must be set outside the libcall,
+        since it goes into a pseudo.  */
+      rtx addr = force_reg (SImode, gen_rtx_SYMBOL_REF (SImode, \"__mulsi3\"));
+      rtx insns = gen_mulsi3_call (operands[0], operands[1], operands[2], addr);
+      first = XVECEXP (insns, 0, 0);
+      last = XVECEXP (insns, 0, XVECLEN (insns, 0) - 1);
+      emit_insn (insns);
     }
+  else
+    {
+      rtx macl = gen_rtx_REG (SImode, MACL_REG);
+
+      first = emit_insn (gen_mul_l (operands[1], operands[2]));
+      /* consec_sets_giv can only recognize the first insn that sets a
+        giv as the giv insn.  So we must tag this also with a REG_EQUAL
+        note.  */
+      last = emit_insn (gen_movsi_i ((operands[0]), macl));
+    }
+  /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
+     invariant code motion can move it.  */
+  REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
+  REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
+  DONE;
 }")
 
 (define_insn "mulsidi3_i"
-  [(set (reg:DI 20)
-       (mult:DI (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
-                (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))))]
+  [(set (reg:SI 20)
+       (truncate:SI
+        (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
+                              (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
+                     (const_int 32))))
+   (set (reg:SI 21)
+       (mult:SI (match_dup 0)
+                (match_dup 1)))]
   "TARGET_SH2"
   "dmuls.l     %1,%0"
   [(set_attr "type" "dmpy")])
 
-(define_expand "mulsidi3"
-  [(set (reg:DI 20)
+(define_insn "mulsidi3"
+  [(set (match_operand:DI 0 "arith_reg_operand" "=r")
+       (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
+                (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
+   (clobber (reg:DI 20))]
+  "TARGET_SH2"
+  "#")
+
+(define_split
+  [(set (match_operand:DI 0 "arith_reg_operand" "")
        (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
                 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
-   (set (match_operand:DI 0 "arith_reg_operand" "")
-       (reg:DI 20))]
+   (clobber (reg:DI 20))]
   "TARGET_SH2"
+  [(const_int 0)]
   "
 {
-  /* We must swap the two words when copying them from MACH/MACL to the
-     output register.  */
-  if (TARGET_LITTLE_ENDIAN)
-    {
-      rtx low_dst = operand_subword (operands[0], 0, 1, DImode);
-      rtx high_dst = operand_subword (operands[0], 1, 1, DImode);
-
-      emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
-
-      emit_insn (gen_rtx (CLOBBER, VOIDmode, operands[0]));
-      emit_move_insn (low_dst, gen_rtx (REG, SImode, 21));
-      emit_move_insn (high_dst, gen_rtx (REG, SImode, 20));
-      DONE;
-    }
+  rtx low_dst = gen_lowpart (SImode, operands[0]);
+  rtx high_dst = gen_highpart (SImode, operands[0]);
+
+  emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
+
+  emit_move_insn (low_dst, gen_rtx_REG (SImode, 21));
+  emit_move_insn (high_dst, gen_rtx_REG (SImode, 20));
+  /* We need something to tag the possible REG_EQUAL notes on to.  */
+  emit_move_insn (operands[0], operands[0]);
+  DONE;
 }")
 
 (define_insn "umulsidi3_i"
-  [(set (reg:DI 20)
-       (mult:DI (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
-                (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))))]
+  [(set (reg:SI 20)
+       (truncate:SI
+        (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
+                              (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
+                     (const_int 32))))
+   (set (reg:SI 21)
+       (mult:SI (match_dup 0)
+                (match_dup 1)))]
   "TARGET_SH2"
   "dmulu.l     %1,%0"



Home | Main Index | Thread Index | Old Index