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]

timode right shifts for ia64


We've got a special double-word shift instruction on ia64, much
like the double-word shift on x86 (fancy that).

I'll be committing a patch soon that will generate these more often...

Tested on ia64-linux.


r~


        * 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.

Index: ia64.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/ia64/ia64.c,v
retrieving revision 1.330
diff -c -p -d -r1.330 ia64.c
*** ia64.c	5 Nov 2004 20:38:36 -0000	1.330
--- ia64.c	5 Nov 2004 23:52:44 -0000
*************** rtx_needs_barrier (rtx x, struct reg_fla
*** 4899,4904 ****
--- 4899,4905 ----
  	  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: ia64.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/ia64/ia64.md,v
retrieving revision 1.136
diff -c -p -d -r1.136 ia64.md
*** ia64.md	10 Sep 2004 11:55:16 -0000	1.136
--- ia64.md	5 Nov 2004 23:52:44 -0000
***************
*** 77,82 ****
--- 77,83 ----
     (UNSPEC_RET_ADDR		26)
     (UNSPEC_SETF_EXP             27)
     (UNSPEC_FR_SQRT_RECIP_APPROX 28)
+    (UNSPEC_SHRP			29)
    ])
  
  (define_constants
***************
*** 335,340 ****
--- 336,346 ----
         (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")
***************
*** 4654,4659 ****
--- 4660,4755 ----
  
  ;; ::::::::::::::::::::
  ;; ::
+ ;; :: 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")])
+ 
+ ;; ::::::::::::::::::::
+ ;; ::
  ;; :: 32 bit Integer Logical operations
  ;; ::
  ;; ::::::::::::::::::::


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