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]

ia64 rotate patterns [Re: shrp]


On Mon, Sep 25, 2000 at 09:22:34AM -0700, David Mosberger wrote:
> Would it be hard for gcc to recognize this:
> 
> 	(w >> n) | (w << (64 - n))
> 
> and translate it into the equivalent of:
> 
> 	asm ("shrp %0=%1,%1,%2" : "=r"(result) : "r"(w), "i"(n))

We'd already had a rotate right pattern in the md file, which works fine
when N is a constant.  However, combine believes the canonical form to be
rotate left, and since we did not define this pattern, we'd not do anything
when N was a constant variable.

I also defined some SImode rotate insn_and_split's for combine to chew on.



r~


	* config/ia64/ia64.c (ia64_print_operand): Define 'e' as 64-n.
	* config/ia64/ia64.md (rotrsi3): Allow variable rotates; don't
	split until after reload.
	(rotlsi3, rotldi3): New.

Index: ia64.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/ia64/ia64.c,v
retrieving revision 1.52
diff -c -p -d -r1.52 ia64.c
*** ia64.c	2000/09/25 13:03:20	1.52
--- ia64.c	2000/09/25 21:54:06
*************** ia64_print_operand_address (stream, addr
*** 3090,3095 ****
--- 3090,3096 ----
     C	Swap and print a comparison operator.
     D	Print an FP comparison operator.
     E    Print 32 - constant, for SImode shifts as extract.
+    e    Print 64 - constant, for DImode rotates.
     F	A floating point constant 0.0 emitted as f0, or 1.0 emitted as f1, or
          a floating point register emitted normally.
     I	Invert a predicate register by adding 1.
*************** ia64_print_operand (file, x, code)
*** 3152,3157 ****
--- 3153,3162 ----
  
      case 'E':
        fprintf (file, HOST_WIDE_INT_PRINT_DEC, 32 - INTVAL (x));
+       return;
+ 
+     case 'e':
+       fprintf (file, HOST_WIDE_INT_PRINT_DEC, 64 - INTVAL (x));
        return;
  
      case 'F':
Index: ia64.md
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/ia64/ia64.md,v
retrieving revision 1.49
diff -c -p -d -r1.49 ia64.md
*** ia64.md	2000/09/24 23:58:24	1.49
--- ia64.md	2000/09/25 21:54:06
***************
*** 3858,3881 ****
  }")
  
  ;; Use mix4.r/shr to implement rotrsi3.  We only get 32 bits of valid result
! ;; here, instead of 64 like the patterns above.
  
  (define_expand "rotrsi3"
    [(set (match_dup 3)
! 	(ior:DI (zero_extend:DI (match_operand:SI 1 "gr_register_operand" ""))
  		(ashift:DI (zero_extend:DI (match_dup 1)) (const_int 32))))
     (set (match_dup 3)
! 	(lshiftrt:DI (match_dup 3)
! 		     (match_operand:DI 2 "nonmemory_operand" "")))
!    (set (match_operand:SI 0 "gr_register_operand" "") (match_dup 4))]
    ""
    "
  {
    if (! shift_32bit_count_operand (operands[2], SImode))
!     FAIL;
!   operands[3] = gen_reg_rtx (DImode);
!   operands[4] = gen_lowpart (SImode, operands[3]);
  }")
  
  ;; ::::::::::::::::::::
  ;; ::
--- 3858,3925 ----
  }")
  
  ;; Use mix4.r/shr to implement rotrsi3.  We only get 32 bits of valid result
! ;; here, instead of 64 like the patterns above.  Keep the pattern together
! ;; until after combine; otherwise it won't get matched often.
  
  (define_expand "rotrsi3"
+   [(set (match_operand:SI 0 "gr_register_operand" "")
+ 	(rotatert:SI (match_operand:SI 1 "gr_register_operand" "")
+ 		     (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
+   ""
+   "
+ {
+   if (GET_MODE (operands[2]) != VOIDmode)
+     {
+       rtx tmp = gen_reg_rtx (DImode);
+       emit_insn (gen_zero_extendsidi2 (tmp, operands[2]));
+       operands[2] = tmp;
+     }
+ }")
+ 
+ (define_insn_and_split "*rotrsi3_internal"
+   [(set (match_operand:SI 0 "gr_register_operand" "=&r")
+ 	(rotatert:SI (match_operand:SI 1 "gr_register_operand" "r")
+ 		     (match_operand:DI 2 "gr_reg_or_5bit_operand" "rM")))]
+   ""
+   "#"
+   "reload_completed"
    [(set (match_dup 3)
! 	(ior:DI (zero_extend:DI (match_dup 1))
  		(ashift:DI (zero_extend:DI (match_dup 1)) (const_int 32))))
     (set (match_dup 3)
! 	(lshiftrt:DI (match_dup 3) (match_dup 2)))]
!   "operands[3] = gen_rtx_REG (DImode, REGNO (operands[0]));")
! 
! (define_expand "rotlsi3"
!   [(set (match_operand:SI 0 "gr_register_operand" "")
! 	(rotate:SI (match_operand:SI 1 "gr_register_operand" "")
! 		   (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
    ""
    "
  {
    if (! shift_32bit_count_operand (operands[2], SImode))
!     {
!       rtx tmp = gen_reg_rtx (SImode);
!       emit_insn (gen_subsi3 (tmp, GEN_INT (32), operands[2]));
!       emit_insn (gen_rotrsi3 (operands[0], operands[1], tmp));
!       DONE;
!     }
  }")
+ 
+ (define_insn_and_split "*rotlsi3_internal"
+   [(set (match_operand:SI 0 "gr_register_operand" "=r")
+ 	(rotate:SI (match_operand:SI 1 "gr_register_operand" "r")
+ 		   (match_operand:SI 2 "shift_32bit_count_operand" "n")))]
+   ""
+   "#"
+   "reload_completed"
+   [(set (match_dup 3)
+ 	(ior:DI (zero_extend:DI (match_dup 1))
+ 		(ashift:DI (zero_extend:DI (match_dup 1)) (const_int 32))))
+    (set (match_dup 3)
+ 	(lshiftrt:DI (match_dup 3) (match_dup 2)))]
+   "operands[3] = gen_rtx_REG (DImode, REGNO (operands[0]));
+    operands[2] = GEN_INT (32 - INTVAL (operands[2]));")
  
  ;; ::::::::::::::::::::
  ;; ::
***************
*** 3967,3972 ****
--- 4011,4034 ----
    "shrp %0 = %1, %1, %2"
    [(set_attr "type" "I")])
  
+ (define_expand "rotldi3"
+   [(set (match_operand:DI 0 "gr_register_operand" "")
+ 	(rotate:DI (match_operand:DI 1 "gr_register_operand" "")
+ 		   (match_operand:DI 2 "nonmemory_operand" "")))]
+   ""
+   "
+ {
+   if (! shift_count_operand (operands[2], DImode))
+     FAIL;
+ }")
+ 
+ (define_insn "*rotldi3_internal"
+   [(set (match_operand:DI 0 "gr_register_operand" "=r")
+ 	(rotate:DI (match_operand:DI 1 "gr_register_operand" "r")
+ 		   (match_operand:DI 2 "shift_count_operand" "M")))]
+   ""
+   "shrp %0 = %1, %1, %e2"
+   [(set_attr "type" "I")])
  
  ;; ::::::::::::::::::::
  ;; ::

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