OSDN Git Service

PR middle-end/19154
authorhutchinsonandy <hutchinsonandy@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 24 Oct 2009 15:36:40 +0000 (15:36 +0000)
committerhutchinsonandy <hutchinsonandy@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 24 Oct 2009 15:36:40 +0000 (15:36 +0000)
* avr.md (QIDI): Add new mode iterator.
(sbrx_branch<mode>): Create new zero extract bit, test and jump
patterns for all QI-DI modes combinations.
(sbrx_and_branch<mode>): Create new and based bit test and jump
patterns for QI-SI modes.
avr.c (avr_out_sbxx_branch): Use only bit number.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@153530 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/config/avr/avr.c
gcc/config/avr/avr.md

index 7c3234f..cb2d709 100644 (file)
@@ -5877,12 +5877,12 @@ avr_hard_regno_rename_ok (unsigned int old_reg ATTRIBUTE_UNUSED,
   return 1;
 }
 
-/* Output a branch that tests a single bit of a register (QI, HI or SImode)
+/* Output a branch that tests a single bit of a register (QI, HI, SI or DImode)
    or memory location in the I/O space (QImode only).
 
    Operand 0: comparison operator (must be EQ or NE, compare bit to zero).
    Operand 1: register operand to test, or CONST_INT memory address.
-   Operand 2: bit number (for QImode operand) or mask (HImode, SImode).
+   Operand 2: bit number.
    Operand 3: label to jump to if the test is true.  */
 
 const char *
@@ -5930,9 +5930,7 @@ avr_out_sbxx_branch (rtx insn, rtx operands[])
       else  /* HImode or SImode */
        {
          static char buf[] = "sbrc %A1,0";
-         int bit_nr = exact_log2 (INTVAL (operands[2])
-                                  & GET_MODE_MASK (GET_MODE (operands[1])));
-
+         int bit_nr = INTVAL (operands[2]);
          buf[3] = (comp == EQ) ? 's' : 'c';
          buf[6] = 'A' + (bit_nr >> 3);
          buf[9] = '0' + (bit_nr & 7);
index b2d6b44..51fc1f9 100644 (file)
 
 ;; Define mode iterator
 (define_mode_iterator QISI [(QI "") (HI "") (SI "")])
+(define_mode_iterator QIDI [(QI "") (HI "") (SI "") (DI "")])
 
 ;;========================================================================
 ;; The following is used by nonlocal_goto and setjmp.
 
 
 ;; Test a single bit in a QI/HI/SImode register.
-(define_insn "*sbrx_branch"
+;; Combine will create zero extract patterns for single bit tests.
+;; permit any mode in source pattern by using VOIDmode.
+
+(define_insn "*sbrx_branch<mode>"
   [(set (pc)
         (if_then_else
         (match_operator 0 "eqne_operator"
-                        [(zero_extract:HI
-                          (match_operand:QI 1 "register_operand" "r")
+                        [(zero_extract:QIDI
+                          (match_operand:VOID 1 "register_operand" "r")
                           (const_int 1)
                           (match_operand 2 "const_int_operand" "n"))
                          (const_int 0)])
                                    (const_int 4))))
    (set_attr "cc" "clobber")])
 
-(define_insn "*sbrx_and_branchhi"
-  [(set (pc)
-        (if_then_else
-        (match_operator 0 "eqne_operator"
-                        [(and:HI
-                          (match_operand:HI 1 "register_operand" "r")
-                          (match_operand:HI 2 "single_one_operand" "n"))
-                         (const_int 0)])
-        (label_ref (match_operand 3 "" ""))
-        (pc)))]
-  ""
-  "* return avr_out_sbxx_branch (insn, operands);"
-  [(set (attr "length")
-       (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
-                          (le (minus (pc) (match_dup 3)) (const_int 2046)))
-                     (const_int 2)
-                     (if_then_else (eq_attr "mcu_mega" "no")
-                                   (const_int 2)
-                                   (const_int 4))))
-   (set_attr "cc" "clobber")])
+;; Same test based on Bitwise AND RTL. Keep this incase gcc changes patterns.
+;; or for old peepholes.
+;; Fixme - bitwise Mask will not work for DImode
 
-(define_insn "*sbrx_and_branchsi"
+(define_insn "*sbrx_and_branch<mode>"
   [(set (pc)
         (if_then_else
         (match_operator 0 "eqne_operator"
-                        [(and:SI
-                          (match_operand:SI 1 "register_operand" "r")
-                          (match_operand:SI 2 "single_one_operand" "n"))
+                        [(and:QISI
+                          (match_operand:QISI 1 "register_operand" "r")
+                          (match_operand:QISI 2 "single_one_operand" "n"))
                          (const_int 0)])
         (label_ref (match_operand 3 "" ""))
         (pc)))]
   ""
-  "* return avr_out_sbxx_branch (insn, operands);"
+{
+    HOST_WIDE_INT bitnumber;
+    bitnumber = exact_log2 (GET_MODE_MASK (<MODE>mode) & INTVAL (operands[2]));
+    operands[2] = GEN_INT (bitnumber);
+    return avr_out_sbxx_branch (insn, operands);
+}
   [(set (attr "length")
        (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
                           (le (minus (pc) (match_dup 3)) (const_int 2046)))