This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

broken ia64 TImode shift


In the course of putting together 128-bit arithmetic support I realized
that
the 128-bit right shift patterns (added November last year) didn't
work; with
optimization turned on they would generate no code at all. This was
because
they generated their results into the input rather than the output.
While doing this I also added left shifts. Rotates should be trivial,
too,
but I don't know which languages can actually generate them and thus
have no
way to test...

Bootstrapped and tested on ia64-unknown-linux-gnu.

Jan

gcc/
2005-01-06  Jan Beulich  <jbeulich@novell.com>

	* config/ia64/ia64.md (ashlti3, ashlti3internal): 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.

---
/home/jbeulich/src/gcc/mainline/2005-01-06.13.34/gcc/config/ia64/ia64.md	2005-01-04
09:22:55.000000000 +0100
+++ 2005-01-06.13.34/gcc/config/ia64/ia64.md	2005-01-11
14:42:45.452868672 +0100
@@ -4322,6 +4331,49 @@
 ;; ::
 ;; ::::::::::::::::::::
 
+(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" "")
@@ -4333,7 +4385,7 @@
 })
 
 (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")))]
   ""
@@ -4342,19 +4394,25 @@
   [(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;
 })
@@ -4370,7 +4428,7 @@
 }) 
 
 (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")))]
   ""
@@ -4379,19 +4437,25 @@
   [(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;
 })

Attachment: gcc-mainline-ia64-TImode-shift.patch
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]