ia64.md (UNSPEC_SHRP): New.
authorRichard Henderson <rth@redhat.com>
Fri, 5 Nov 2004 23:54:30 +0000 (15:54 -0800)
committerRichard Henderson <rth@gcc.gnu.org>
Fri, 5 Nov 2004 23:54:30 +0000 (15:54 -0800)
        * ia64.md (UNSPEC_SHRP): New.
        (dshift_count_operand): New.
        (ashrti3, ashrti3_internal, lshrti3, lshrti3_internal, shrp): New.
        * ia64.c (rtx_needs_barrier): Handle UNSPEC_SHRP.

From-SVN: r90149

gcc/ChangeLog
gcc/config/ia64/ia64.c
gcc/config/ia64/ia64.md

index 749e21da0a3b2d34d54f455bc0e95a831c59b935..5cf30867886ebccfb26cbff95197d1b617eb15ce 100644 (file)
@@ -1,3 +1,10 @@
+2004-11-05  Richard Henderson  <rth@redhat.com>
+
+       * ia64.md (UNSPEC_SHRP): New.
+       (dshift_count_operand): New.
+       (ashrti3, ashrti3_internal, lshrti3, lshrti3_internal, shrp): New.
+       * ia64.c (rtx_needs_barrier): Handle UNSPEC_SHRP.
+
 2004-11-05  Joseph S. Myers  <joseph@codesourcery.com>
 
        * c-typeck.c (output_init_element): Return early if value is
index 5f8dcaa5afd7f9ef7075396cff663c9b73ee02db..0b65686512c0414fe226a74aed988f135079f133 100644 (file)
@@ -4899,6 +4899,7 @@ rtx_needs_barrier (rtx x, struct reg_flags flags, int pred)
          break;
 
        case UNSPEC_FR_RECIP_APPROX:
+       case UNSPEC_SHRP:
          need_barrier = rtx_needs_barrier (XVECEXP (x, 0, 0), flags, pred);
          need_barrier |= rtx_needs_barrier (XVECEXP (x, 0, 1), flags, pred);
          break;
index 31f14bb1765cfc46287760677e2ec522ec726900..4a01ba4d9042d946e2175a0a5370fe49e2271517 100644 (file)
@@ -77,6 +77,7 @@
    (UNSPEC_RET_ADDR            26)
    (UNSPEC_SETF_EXP             27)
    (UNSPEC_FR_SQRT_RECIP_APPROX 28)
+   (UNSPEC_SHRP                        29)
   ])
 
 (define_constants
        (and (match_code "const_int")
            (match_test "CONST_OK_FOR_J (INTVAL (op))"))))
 
+;; True if OP is a 7 bit immediate operand.
+(define_predicate "dshift_count_operand"
+  (and (match_code "const_int")
+       (match_test "INTVAL (op) >= 0 && INTVAL (op) < 128")))
+
 ;; True if OP is a 6 bit immediate operand.
 (define_predicate "shift_count_operand"
   (and (match_code "const_int")
 \f
 ;; ::::::::::::::::::::
 ;; ::
+;; :: 128 bit Integer Shifts and Rotates
+;; ::
+;; ::::::::::::::::::::
+
+(define_expand "ashrti3"
+  [(set (match_operand:TI 0 "gr_register_operand" "")
+       (ashiftrt:TI (match_operand:TI 1 "gr_register_operand" "")
+                    (match_operand:DI 2 "nonmemory_operand" "")))]
+  ""
+{
+  if (!dshift_count_operand (operands[2], DImode))
+    FAIL;
+})
+
+(define_insn_and_split "*ashrti3_internal"
+  [(set (match_operand:TI 0 "gr_register_operand" "=r")
+       (ashiftrt:TI (match_operand:TI 1 "gr_register_operand" "r")
+                    (match_operand:DI 2 "dshift_count_operand" "n")))]
+  ""
+  "#"
+  "reload_completed"
+  [(const_int 0)]
+{
+  HOST_WIDE_INT shift = INTVAL (operands[2]);
+  rtx lo = gen_lowpart (DImode, operands[1]);
+  rtx hi = gen_highpart (DImode, operands[1]);
+  rtx shiftlo = GEN_INT (shift & 63);
+
+  if (shift & 64)
+    {
+      emit_insn (gen_ashrdi3 (lo, hi, shiftlo));
+      emit_insn (gen_ashrdi3 (hi, hi, GEN_INT (63)));
+    }
+  else
+    {
+      emit_insn (gen_shrp (lo, hi, lo, shiftlo));
+      emit_insn (gen_ashrdi3 (hi, hi, shiftlo));
+    }
+  DONE;
+})
+
+(define_expand "lshrti3"
+  [(set (match_operand:TI 0 "gr_register_operand" "")
+        (lshiftrt:TI (match_operand:TI 1 "gr_register_operand" "")
+                     (match_operand:DI 2 "nonmemory_operand" "")))]
+  ""
+{ 
+  if (!dshift_count_operand (operands[2], DImode))
+    FAIL;
+}) 
+
+(define_insn_and_split "*lshrti3_internal"
+  [(set (match_operand:TI 0 "gr_register_operand" "=r")
+       (lshiftrt:TI (match_operand:TI 1 "gr_register_operand" "r")
+                    (match_operand:DI 2 "dshift_count_operand" "n")))]
+  ""
+  "#"
+  "reload_completed"
+  [(const_int 0)]
+{
+  HOST_WIDE_INT shift = INTVAL (operands[2]);
+  rtx lo = gen_lowpart (DImode, operands[1]);
+  rtx hi = gen_highpart (DImode, operands[1]);
+  rtx shiftlo = GEN_INT (shift & 63);
+
+  if (shift & 64)
+    {
+      emit_insn (gen_lshrdi3 (lo, hi, shiftlo));
+      emit_move_insn (hi, const0_rtx);
+    }
+  else
+    {
+      emit_insn (gen_shrp (lo, hi, lo, shiftlo));
+      emit_insn (gen_lshrdi3 (hi, hi, shiftlo));
+    }
+  DONE;
+})
+
+(define_insn "shrp"
+  [(set (match_operand:DI 0 "gr_register_operand" "=r")
+       (unspec:DI [(match_operand:DI 1 "gr_register_operand" "r")
+                   (match_operand:DI 2 "gr_register_operand" "r")
+                   (match_operand:DI 3 "shift_count_operand" "M")]
+                  UNSPEC_SHRP))]
+  ""
+  "shrp %0 = %1, %2, %3"
+  [(set_attr "itanium_class" "ishf")])
+\f
+;; ::::::::::::::::::::
+;; ::
 ;; :: 32 bit Integer Logical operations
 ;; ::
 ;; ::::::::::::::::::::