(truncdisi2): Change from define_insn to define_expand.
authorJim Wilson <wilson@gcc.gnu.org>
Sat, 18 Jun 1994 20:53:45 +0000 (13:53 -0700)
committerJim Wilson <wilson@gcc.gnu.org>
Sat, 18 Jun 1994 20:53:45 +0000 (13:53 -0700)
(truncdihi2, truncdiqi2, extendsidi2): Likewise.
(extendsidi2_internal): New pattern.

From-SVN: r7520

gcc/config/mips/mips.md

index f21c90a..a89d114 100644 (file)
@@ -1833,34 +1833,49 @@ move\\t%0,%z4\\n\\
    (set_attr "mode"    "SF")
    (set_attr "length"  "1")])
 
-;; ??? This should be a define expand.
-;; See the zero_extendsidi2 pattern.
-(define_insn "truncdisi2"
-  [(set (match_operand:SI 0 "register_operand" "=d")
-       (truncate:SI (match_operand:DI 1 "register_operand" "d")))]
+
+;; The optimizer doesn't deal well with truncate operators, so we completely
+;; avoid them by using define expands here.
+
+(define_expand "truncdisi2"
+  [(set (match_operand:DI 2 "register_operand" "=d")
+       (ashift:DI (match_operand:DI 1 "register_operand" "d")
+                    (const_int 32)))
+   (set (match_operand:DI 3 "register_operand" "=d")
+       (ashiftrt:DI (match_dup 2)
+                  (const_int 32)))
+   (set (match_operand:SI 0 "register_operand" "=d")
+       (subreg:SI (match_dup 3) 0))]
   "TARGET_64BIT"
-  "dsll\\t%0,%1,32\;dsra\\t%0,%0,32"
-  [(set_attr "type"    "darith")
-   (set_attr "mode"    "SI")
-   (set_attr "length"  "2")])
+  "
+{
+  operands[2] = gen_reg_rtx (DImode);
+  operands[3] = gen_reg_rtx (DImode);
+}")
 
-(define_insn "truncdihi2"
-  [(set (match_operand:HI 0 "register_operand" "=d")
-       (truncate:HI (match_operand:DI 1 "register_operand" "d")))]
+(define_expand "truncdihi2"
+  [(set (match_operand:DI 2 "register_operand" "=d")
+       (and:DI (match_operand:DI 1 "register_operand" "d")
+               (const_int 65535)))
+   (set (match_operand:HI 0 "register_operand" "=d")
+       (subreg:HI (match_dup 2) 0))]
   "TARGET_64BIT"
-  "andi\\t%0,%1,0xffff"
-  [(set_attr "type"    "darith")
-   (set_attr "mode"    "HI")
-   (set_attr "length"  "1")])
+  "
+{
+  operands[2] = gen_reg_rtx (DImode);
+}")
 
-(define_insn "truncdiqi2"
-  [(set (match_operand:QI 0 "register_operand" "=d")
-       (truncate:QI (match_operand:DI 1 "register_operand" "d")))]
+(define_expand "truncdiqi2"
+  [(set (match_operand:DI 2 "register_operand" "=d")
+       (and:DI (match_operand:DI 1 "register_operand" "d")
+               (const_int 255)))
+   (set (match_operand:QI 0 "register_operand" "=d")
+       (subreg:QI (match_dup 2) 0))]
   "TARGET_64BIT"
-  "andi\\t%0,%1,0x00ff"
-  [(set_attr "type"    "darith")
-   (set_attr "mode"    "QI")
-   (set_attr "length"  "1")])
+  "
+{
+  operands[2] = gen_reg_rtx (DImode);
+}")
 \f
 ;;
 ;;  ....................
@@ -1870,8 +1885,7 @@ move\\t%0,%z4\\n\\
 ;;  ....................
 
 ;; Extension insns.
-;; Those for integer source operand
-;; are ordered widest source type first.
+;; Those for integer source operand are ordered widest source type first.
 
 (define_expand "zero_extendsidi2"
   [(set (match_operand:DI 0 "register_operand" "")
@@ -1903,7 +1917,6 @@ move\\t%0,%z4\\n\\
    (set_attr "mode"    "DI")
    (set_attr "length"  "1,2")])
 
-
 (define_insn "zero_extendhisi2"
   [(set (match_operand:SI 0 "register_operand" "=d,d,d")
        (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))]
@@ -1988,24 +2001,37 @@ move\\t%0,%z4\\n\\
 ;;  ....................
 
 ;; Extension insns.
-;; Those for integer source operand
-;; are ordered widest source type first.
-
-;; ??? This should be a define_expand.
+;; Those for integer source operand are ordered widest source type first.
 
-(define_insn "extendsidi2"
-  [(set (match_operand:DI 0 "register_operand" "=d,d,d")
-       (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))]
+(define_expand "extendsidi2"
+  [(set (match_operand:DI 0 "register_operand" "")
+       (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
   "TARGET_64BIT"
-  "*
+  "
 {
-  if (which_alternative == 0)
-    return \"dsll\\t%0,%1,32\;dsra\\t%0,%0,32\";
-  return mips_move_1word (operands, insn, FALSE);
-}"
-  [(set_attr "type"    "arith,load,load")
+  if (optimize && GET_CODE (operands[1]) == MEM)
+    operands[1] = force_not_mem (operands[1]);
+
+  if (GET_CODE (operands[1]) != MEM)
+    {
+      rtx op1   = gen_lowpart (DImode, operands[1]);
+      rtx temp  = gen_reg_rtx (DImode);
+      rtx shift = gen_rtx (CONST_INT, VOIDmode, 32);
+
+      emit_insn (gen_ashldi3 (temp, op1, shift));
+      emit_insn (gen_ashrdi3 (operands[0], temp, shift));
+      DONE;
+    }
+}")
+
+(define_insn "extendsidi2_internal"
+  [(set (match_operand:DI 0 "register_operand" "=d,d")
+       (sign_extend:DI (match_operand:SI 1 "memory_operand" "R,m")))]
+  "TARGET_64BIT"
+  "* return mips_move_1word (operands, insn, FALSE);"
+  [(set_attr "type"    "load")
    (set_attr "mode"    "DI")
-   (set_attr "length"  "2,1,2")])
+   (set_attr "length"  "1,2")])
 
 ;; These patterns originally accepted general_operands, however, slightly
 ;; better code is generated by only accepting register_operands, and then