ia64.c (ia64_print_operand): Define 'e' as 64-n.
authorRichard Henderson <rth@cygnus.com>
Mon, 25 Sep 2000 22:06:29 +0000 (15:06 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Mon, 25 Sep 2000 22:06:29 +0000 (15:06 -0700)
        * 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.

From-SVN: r36632

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

index 0e200f9c5516b9ceae627e1b120c222f4e672d13..d80a03c65b61086f9e821056b3a8074b1d246e64 100644 (file)
@@ -1,3 +1,10 @@
+2000-09-25  Richard Henderson  <rth@cygnus.com>
+
+       * 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.
+
 2000-09-25  Gabriel Dos Reis  <gdr@codesourcery.com>
 
        * diagnostic.c (output_last_position): Define.
index fe74c72d08e65d222cde1c2771081a59499bfad3..2d77d89dde0a04a054e8103224075c87428bb9ef 100644 (file)
@@ -3090,6 +3090,7 @@ ia64_print_operand_address (stream, address)
    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.
@@ -3154,6 +3155,10 @@ ia64_print_operand (file, x, code)
       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':
       if (x == CONST0_RTX (GET_MODE (x)))
        str = reg_names [FR_REG (0)];
index 11b14c01fe03d48556746bcdeaae2c7ff6de699a..52c1c7c464f8c9102c6de90ebdf565eba552638c 100644 (file)
 }")
 
 ;; Use mix4.r/shr to implement rotrsi3.  We only get 32 bits of valid result
-;; here, instead of 64 like the patterns above.
+;; 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_operand:SI 1 "gr_register_operand" ""))
+       (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_operand:DI 2 "nonmemory_operand" "")))
-   (set (match_operand:SI 0 "gr_register_operand" "") (match_dup 4))]
+       (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))
-    FAIL;
-  operands[3] = gen_reg_rtx (DImode);
-  operands[4] = gen_lowpart (SImode, operands[3]);
+    {
+      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]));")
 \f
 ;; ::::::::::::::::::::
 ;; ::
   "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")])
 \f
 ;; ::::::::::::::::::::
 ;; ::