ia64.md (ashlti3, [...]): New.
authorJan Beulich <jbeulich@novell.com>
Thu, 13 Jan 2005 07:12:11 +0000 (07:12 +0000)
committerJan Beulich <jbeulich@gcc.gnu.org>
Thu, 13 Jan 2005 07:12:11 +0000 (07:12 +0000)
gcc/
2005-01-13  Jan Beulich  <jbeulich@novell.com>

* config/ia64/ia64.md (ashlti3, ashlti3_internal): New.
(ashrti3_internal): Indicate output is early clobber. Generate result
into output rather than first input. Use move for low word of output
if shift count is exactly 64.
(lshrti3_internal): Likewise.

From-SVN: r93596

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

index d0846592770cc0986bc640251a7881310d2eebb6..a514b59501f7ed6988ef267ccc7562039a826e3d 100644 (file)
@@ -1,3 +1,11 @@
+2005-01-13  Jan Beulich  <jbeulich@novell.com>
+
+       * config/ia64/ia64.md (ashlti3, ashlti3_internal): New.
+       (ashrti3_internal): Indicate output is early clobber. Generate result
+       into output rather than first input. Use move for low word of output
+       if shift count is exactly 64.
+       (lshrti3_internal): Likewise.
+
 2005-01-13  Hans-Peter Nilsson  <hp@bitrange.com>
 
        PR target/18329
index a41398d1cd8b6c8cbf3c0c19e3a5ad815559b7c9..c406a797f41a2a0f78479dbafe1400a6a508c964 100644 (file)
 ;; ::
 ;; ::::::::::::::::::::
 
+(define_expand "ashlti3"
+  [(set (match_operand:TI 0 "gr_register_operand" "")
+       (ashift: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 "*ashlti3_internal"
+  [(set (match_operand:TI 0 "gr_register_operand" "=&r")
+       (ashift: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 rl = gen_lowpart (DImode, operands[0]);
+  rtx rh = gen_highpart (DImode, operands[0]);
+  rtx lo = gen_lowpart (DImode, operands[1]);
+  rtx shiftlo = GEN_INT (shift & 63);
+
+  if (shift & 64)
+    {
+      emit_move_insn (rl, const0_rtx);
+      if (shift & 63)
+       emit_insn (gen_ashldi3 (rh, lo, shiftlo));
+      else
+       emit_move_insn (rh, lo);
+    }
+  else
+    {
+      rtx hi = gen_highpart (DImode, operands[1]);
+
+      emit_insn (gen_shrp (rh, hi, lo, GEN_INT (-shift & 63)));
+      emit_insn (gen_ashldi3 (rl, lo, shiftlo));
+    }
+  DONE;
+})
+
 (define_expand "ashrti3"
   [(set (match_operand:TI 0 "gr_register_operand" "")
        (ashiftrt:TI (match_operand:TI 1 "gr_register_operand" "")
 })
 
 (define_insn_and_split "*ashrti3_internal"
-  [(set (match_operand:TI 0 "gr_register_operand" "=r")
+  [(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")))]
   ""
   [(const_int 0)]
 {
   HOST_WIDE_INT shift = INTVAL (operands[2]);
-  rtx lo = gen_lowpart (DImode, operands[1]);
+  rtx rl = gen_lowpart (DImode, operands[0]);
+  rtx rh = gen_highpart (DImode, operands[0]);
   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)));
+      if (shift & 63)
+       emit_insn (gen_ashrdi3 (rl, hi, shiftlo));
+      else
+       emit_move_insn (rl, hi);
+      emit_insn (gen_ashrdi3 (rh, hi, GEN_INT (63)));
     }
   else
     {
-      emit_insn (gen_shrp (lo, hi, lo, shiftlo));
-      emit_insn (gen_ashrdi3 (hi, hi, shiftlo));
+      rtx lo = gen_lowpart (DImode, operands[1]);
+
+      emit_insn (gen_shrp (rl, hi, lo, shiftlo));
+      emit_insn (gen_ashrdi3 (rh, hi, shiftlo));
     }
   DONE;
 })
 }) 
 
 (define_insn_and_split "*lshrti3_internal"
-  [(set (match_operand:TI 0 "gr_register_operand" "=r")
+  [(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")))]
   ""
   [(const_int 0)]
 {
   HOST_WIDE_INT shift = INTVAL (operands[2]);
-  rtx lo = gen_lowpart (DImode, operands[1]);
+  rtx rl = gen_lowpart (DImode, operands[0]);
+  rtx rh = gen_highpart (DImode, operands[0]);
   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);
+      if (shift & 63)
+       emit_insn (gen_lshrdi3 (rl, hi, shiftlo));
+      else
+       emit_move_insn (rl, hi);
+      emit_move_insn (rh, const0_rtx);
     }
   else
     {
-      emit_insn (gen_shrp (lo, hi, lo, shiftlo));
-      emit_insn (gen_lshrdi3 (hi, hi, shiftlo));
+      rtx lo = gen_lowpart (DImode, operands[1]);
+
+      emit_insn (gen_shrp (rl, hi, lo, shiftlo));
+      emit_insn (gen_lshrdi3 (rh, hi, shiftlo));
     }
   DONE;
 })