OSDN Git Service

* sh.md (udivsi3_i1, divsi3_i1, umulhisi3_i, mulhisi3_i): Name.
authoramylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 16 Feb 2000 00:59:17 +0000 (00:59 +0000)
committeramylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 16 Feb 2000 00:59:17 +0000 (00:59 +0000)
(smulsi3_highpart_i): Name.
(udivsi3): Wrap emitted insns in REG_LIBCALL / REG_RETVAL notes.
(divsi3, mulhisi3, umulhisi3, mulsidi3, umulsidi3): Likewise.
(smulsi3_highpart, umulsi3_highpart): Likewise.

(mulsidi3_i, umulsidi3_i): Make rtl describe operation
correctly independent of endianness.
(mulsidi3, umulsidi3): Now define_insn.  Hide details that
confuse the optimizers.
(mulsidi3+1, umulsidi3+1): New define_split.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@31997 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/sh/sh.md

index 2638364..a9ad434 100644 (file)
@@ -1,3 +1,17 @@
+Wed Feb 16 00:58:06 2000  J"orn Rennecke <amylaar@cygnus.co.uk>
+
+       * sh.md (udivsi3_i1, divsi3_i1, umulhisi3_i, mulhisi3_i): Name.
+       (smulsi3_highpart_i): Name.
+       (udivsi3): Wrap emitted insns in REG_LIBCALL / REG_RETVAL notes.
+       (divsi3, mulhisi3, umulhisi3, mulsidi3, umulsidi3): Likewise.
+       (smulsi3_highpart, umulsi3_highpart): Likewise.
+
+       (mulsidi3_i, umulsidi3_i): Make rtl describe operation
+       correctly independent of endianness.
+       (mulsidi3, umulsidi3): Now define_insn.  Hide details that
+       confuse the optimizers.
+       (mulsidi3+1, umulsidi3+1): New define_split.
+
 Tue Feb 15 23:22:26 2000  Andrew Haley  <aph@cygnus.com>
 
        * config/sh/sh.md: Guard insn splits against illegal registers.
index 61720e0..3a662cd 100644 (file)
 ;; 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))
    (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)))
   ""
   "
 {
+  rtx first, last;
+
   operands[3] = gen_reg_rtx(SImode);
+  /* Emit the move of the address to a pseudo outside of the libcall.  */
   if (TARGET_HARD_SH4)
     {
-      emit_move_insn (gen_rtx (REG, SImode, 4), operands[1]);
-      emit_move_insn (gen_rtx (REG, SImode, 5), operands[2]);
       emit_move_insn (operands[3],
                      gen_rtx_SYMBOL_REF (SImode, \"__udivsi3_i4\"));
       if (TARGET_FPU_SINGLE)
-       emit_insn (gen_udivsi3_i4_single (operands[0], operands[3]));
+       last = gen_udivsi3_i4_single (operands[0], operands[3]);
       else
-       emit_insn (gen_udivsi3_i4 (operands[0], operands[3]));
-      DONE;
+       last = gen_udivsi3_i4 (operands[0], operands[3]);
+    }
+  else
+    {
+      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 ""
+(define_insn "divsi3_i1"
   [(set (match_operand:SI 0 "register_operand" "=z")
        (div:SI (reg:SI 4) (reg:SI 5)))
    (clobber (reg:SI 18))
    (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)))
   ""
   "
 {
+  rtx first, last;
+
   operands[3] = gen_reg_rtx(SImode);
+  /* Emit the move of the address to a pseudo outside of the libcall.  */
   if (TARGET_HARD_SH4)
     {
-      emit_move_insn (gen_rtx (REG, SImode, 4), operands[1]);
-      emit_move_insn (gen_rtx (REG, SImode, 5), operands[2]);
       emit_move_insn (operands[3],
                      gen_rtx_SYMBOL_REF (SImode, \"__sdivsi3_i4\"));
       if (TARGET_FPU_SINGLE)
-       emit_insn (gen_divsi3_i4_single (operands[0], operands[3]));
+       last = gen_divsi3_i4_single (operands[0], operands[3]);
       else
-       emit_insn (gen_divsi3_i4 (operands[0], operands[3]));
-      DONE;
+       last = gen_divsi3_i4 (operands[0], operands[3]);
     }
+  else
+    {
+      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;
 }")
 \f
 ;; -------------------------------------------------------------------------
 ;; 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"))))]
   "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"))
    (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)
    (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.
 }")
 
 (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);
+  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_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;
-    }
+  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"
   [(set_attr "type" "dmpy")])
 
-(define_expand "umulsidi3"
-  [(set (reg:DI 20)
+(define_insn "umulsidi3"
+  [(set (match_operand:DI 0 "arith_reg_operand" "=r")
+       (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
+                (zero_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 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
                 (zero_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);
+  rtx low_dst = gen_lowpart (SImode, operands[0]);
+  rtx high_dst = gen_highpart (SImode, operands[0]);
 
-      emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
+  emit_insn (gen_umulsidi3_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;
-    }
+  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 ""
+(define_insn "smulsi3_highpart_i"
   [(set (reg:SI 20)
        (truncate:SI
         (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
    (set (match_operand:SI 0 "arith_reg_operand" "")
        (reg:SI 20))]
   "TARGET_SH2"
-  "")
+  "
+{
+  rtx first, last;
 
-(define_insn ""
+  first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
+  last = emit_move_insn (operands[0], gen_rtx_REG (SImode, 20));
+  /* 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 "umulsi3_highpart_i"
   [(set (reg:SI 20)
        (truncate:SI
         (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
    (set (match_operand:SI 0 "arith_reg_operand" "")
        (reg:SI 20))]
   "TARGET_SH2"
-  "")
+  "
+{
+  rtx first, last;
+
+  first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
+  last = emit_move_insn (operands[0], gen_rtx_REG (SImode, 20));
+  /* 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;
+}")
 \f
 ;; -------------------------------------------------------------------------
 ;; Logical operations