]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR target/50446 ([avr] Implement rotate patterns with offset 1)
authorGeorg-Johann Lay <avr@gjlay.de>
Fri, 23 Sep 2011 10:14:23 +0000 (10:14 +0000)
committerGeorg-Johann Lay <gjl@gcc.gnu.org>
Fri, 23 Sep 2011 10:14:23 +0000 (10:14 +0000)
PR target/50446
* config/avr/avr.md (rotlqi3): Support all offsets 0..7.
(rotlqi3_4): Turn insn into expander.
(*rotlqi3): New insn.
(rotlhi3, rotlsi3): Support rotate left/right by 1.
(*rotlhi2.1, *rotlhi2.15): New insns.
(*rotlsi2.1, *rotlsi2.31): New insns.
* config/avr/constraints.md (C03, C05, C06, C07): New constraints.

From-SVN: r179116

gcc/ChangeLog
gcc/config/avr/avr.md
gcc/config/avr/constraints.md

index 096dcabf1125d0c8b298db6a211399a1df994dfd..5fcf03cfb82e57066000abea3ec861f5faadb2c1 100644 (file)
@@ -1,3 +1,14 @@
+2011-09-23  Georg-Johann Lay  <avr@gjlay.de>
+
+       PR target/50446
+       * config/avr/avr.md (rotlqi3): Support all offsets 0..7.
+       (rotlqi3_4): Turn insn into expander.
+       (*rotlqi3): New insn.
+       (rotlhi3, rotlsi3): Support rotate left/right by 1.
+       (*rotlhi2.1, *rotlhi2.15): New insns.
+       (*rotlsi2.1, *rotlsi2.31): New insns.
+       * config/avr/constraints.md (C03, C05, C06, C07): New constraints.
+
 2011-09-23  Bin Cheng  <bin.cheng@arm.com>
 
        * config/arm/bpabi.h (BE8_LINK_SPEC): Add cortex-m arch 
index ab17104453e8c1ab750e1396f84b692f153945b8..c7a28c74f0eb074bb1eec5f5b2a106570b6ccd0b 100644 (file)
 
 (define_expand "rotlqi3"
   [(set (match_operand:QI 0 "register_operand" "")
-       (rotate:QI (match_operand:QI 1 "register_operand" "")
-                  (match_operand:QI 2 "const_int_operand" "")))]
+        (rotate:QI (match_operand:QI 1 "register_operand" "")
+                   (match_operand:QI 2 "const_0_to_7_operand" "")))]
   ""
-  "
-{
-  if (!CONST_INT_P (operands[2]) || (INTVAL (operands[2]) != 4))
-    FAIL;
-}")
+  {
+    if (!CONST_INT_P (operands[2]))
+      FAIL;
 
-(define_insn "rotlqi3_4"
-  [(set (match_operand:QI 0 "register_operand" "=r")
-       (rotate:QI (match_operand:QI 1 "register_operand" "0")
-                  (const_int 4)))]
+    operands[2] = gen_int_mode (INTVAL (operands[2]) & 7, QImode);
+  })
+
+;; Expander used by __builtin_avr_swap
+(define_expand "rotlqi3_4"
+  [(set (match_operand:QI 0 "register_operand" "")
+        (rotate:QI (match_operand:QI 1 "register_operand" "")
+                   (const_int 4)))])
+
+(define_insn "*rotlqi3"
+  [(set (match_operand:QI 0 "register_operand"               "=r,r,r  ,r  ,r  ,r  ,r  ,r")
+        (rotate:QI (match_operand:QI 1 "register_operand"     "0,0,0  ,0  ,0  ,0  ,0  ,0")
+                   (match_operand:QI 2 "const_0_to_7_operand" "P,K,C03,C04,C05,C06,C07,L")))]
   ""
-  "swap %0"
-  [(set_attr "length" "1")
-   (set_attr "cc" "none")])
+  "@
+       lsl %0\;adc %0,__zero_reg__
+       lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
+       swap %0\;bst %0,0\;ror %0\;bld %0,7
+       swap %0
+       swap %0\;lsl %0\;adc %0,__zero_reg__
+       swap %0\;lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
+       bst %0,0\;ror %0\;bld %0,7
+       "
+  [(set_attr "length" "2,4,4,1,3,5,3,0")
+   (set_attr "cc" "set_n,set_n,clobber,none,set_n,set_n,clobber,none")])
 
 ;; Split all rotates of HI,SI and DImode registers where rotation is by
 ;; a whole number of bytes.  The split creates the appropriate moves and
 (define_mode_attr rotx [(DI "&r,&r,X") (SI "&r,&r,X") (HI "X,X,X")])
 (define_mode_attr rotsmode [(DI "QI") (SI "HI") (HI "QI")])
 
+;; "rotlhi3"
+;; "rotlsi3"
+;; "rotldi3"
 (define_expand "rotl<mode>3"
   [(parallel [(set (match_operand:HIDI 0 "register_operand" "")
-                  (rotate:HIDI (match_operand:HIDI 1 "register_operand" "")
-                               (match_operand:VOID 2 "const_int_operand" "")))
-               (clobber (match_dup 3))])]
+                   (rotate:HIDI (match_operand:HIDI 1 "register_operand" "")
+                                (match_operand:VOID 2 "const_int_operand" "")))
+              (clobber (match_dup 3))])]
   ""
   {
-    if (CONST_INT_P (operands[2])
-        && 0 == INTVAL (operands[2]) % 8)
+    int offset;
+
+    if (!CONST_INT_P (operands[2]))
+      FAIL;
+
+    offset = INTVAL (operands[2]);
+    if (0 == offset % 8)
       {
-        if (AVR_HAVE_MOVW && 0 == INTVAL (operands[2]) % 16)
+        if (AVR_HAVE_MOVW && 0 == offset % 16)
           operands[3] = gen_rtx_SCRATCH (<rotsmode>mode);
         else
           operands[3] = gen_rtx_SCRATCH (QImode);
       }
+    else if (<MODE>mode != DImode
+             && (offset == 1
+                 || offset == GET_MODE_BITSIZE (<MODE>mode) -1))
+      {
+        /*; Support rotate left/right by 1  */
+
+        emit_move_insn (operands[0],
+                        gen_rtx_ROTATE (<MODE>mode, operands[1], operands[2]));
+        DONE;
+      }
     else
       FAIL;
   })
 
+(define_insn "*rotlhi2.1"
+  [(set (match_operand:HI 0 "register_operand"           "=r")
+        (rotate:HI (match_operand:HI 1 "register_operand" "0")
+                   (const_int 1)))]
+  ""
+  "lsl %A0\;rol %B0\;adc %A0,__zero_reg__"
+  [(set_attr "length" "3")
+   (set_attr "cc" "clobber")])
+
+(define_insn "*rotlhi2.15"
+  [(set (match_operand:HI 0 "register_operand"           "=r")
+        (rotate:HI (match_operand:HI 1 "register_operand" "0")
+                   (const_int 15)))]
+  ""
+  "bst %A0,0\;ror %B0\;ror %A0\;bld %B0,7"
+  [(set_attr "length" "3")
+   (set_attr "cc" "clobber")])
+
+(define_insn "*rotlsi2.1"
+  [(set (match_operand:SI 0 "register_operand"           "=r")
+        (rotate:SI (match_operand:SI 1 "register_operand" "0")
+                   (const_int 1)))]
+  ""
+  "lsl %A0\;rol %B0\;rol %C0\;rol %D0\;adc %A0,__zero_reg__"
+  [(set_attr "length" "5")
+   (set_attr "cc" "clobber")])
+
+(define_insn "*rotlsi2.31"
+  [(set (match_operand:SI 0 "register_operand"           "=r")
+        (rotate:SI (match_operand:SI 1 "register_operand" "0")
+                   (const_int 31)))]
+  ""
+  "bst %A0,0\;ror %D0\;ror %C0\;ror %B0\;ror %A0\;bld %D0,7"
+  [(set_attr "length" "6")
+   (set_attr "cc" "clobber")])
 
 ;; Overlapping non-HImode registers often (but not always) need a scratch.
 ;; The best we can do is use early clobber alternative "#&r" so that
 ;; allocation does not prefer non-overlapping.
 
 
-; Split word aligned rotates using scratch that is mode dependent.
+;; Split word aligned rotates using scratch that is mode dependent.
+
+;; "*rotwhi"
+;; "*rotwsi"
+;; "*rotwdi"
 (define_insn_and_split "*rotw<mode>"
   [(set (match_operand:HIDI 0 "register_operand" "=r,r,#&r")
         (rotate:HIDI (match_operand:HIDI 1 "register_operand" "0,r,r")
   })
 
 
-; Split byte aligned rotates using scratch that is always QI mode.
+;; Split byte aligned rotates using scratch that is always QI mode.
+
+;; "*rotbhi"
+;; "*rotbsi"
+;; "*rotbdi"
 (define_insn_and_split "*rotb<mode>"
   [(set (match_operand:HIDI 0 "register_operand" "=r,r,#&r")
         (rotate:HIDI (match_operand:HIDI 1 "register_operand" "0,r,r")
index d6c172f86e29a46dd1619e9764d836ef97b4b66b..f02c1978673b0d2a1b28d58fa34ea0a431e48c2e 100644 (file)
   (and (match_code "mem")
        (match_test "extra_constraint_Q (op)")))
 
+(define_constraint "C03"
+  "Constant integer 3."
+  (and (match_code "const_int")
+       (match_test "ival == 3")))
+
 (define_constraint "C04"
   "Constant integer 4."
   (and (match_code "const_int")
        (match_test "ival == 4")))
 
+(define_constraint "C05"
+  "Constant integer 5."
+  (and (match_code "const_int")
+       (match_test "ival == 5")))
+
+(define_constraint "C06"
+  "Constant integer 6."
+  (and (match_code "const_int")
+       (match_test "ival == 6")))
+
+(define_constraint "C07"
+  "Constant integer 7."
+  (and (match_code "const_int")
+       (match_test "ival == 7")))
+
 (define_constraint "Ca2"
   "Constant 2-byte integer that allows AND without clobber register."
   (and (match_code "const_int")