Index: gcc/config/avr/predicates.md
===================================================================
--- gcc/config/avr/predicates.md	(revision 142396)
+++ gcc/config/avr/predicates.md	(working copy)
@@ -105,3 +105,7 @@
   (and (match_code "mem")
        (ior (match_test "register_operand (XEXP (op, 0), mode)")
             (match_test "CONSTANT_ADDRESS_P (XEXP (op, 0))"))))
+
+;; True for ASHIFTRT & LSHIFTRT
+(define_predicate "shiftrt_operator"
+  (match_code "ashiftrt,lshiftrt"))
Index: gcc/config/avr/avr.md
===================================================================
--- gcc/config/avr/avr.md	(revision 142396)
+++ gcc/config/avr/avr.md	(working copy)
@@ -1,4 +1,3 @@
-;; -*- Mode: Scheme -*-
 ;;   Machine description for GNU compiler,
 ;;   for ATMEL AVR micro controllers.
 ;;   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008
@@ -57,6 +56,9 @@
    (UNSPECV_PROLOGUE_SAVES	0)
    (UNSPECV_EPILOGUE_RESTORES	1)])
 
+(define_mode_iterator HISI [HI SI])
+(define_mode_iterator QIHISI [QI HI SI])
+
 (include "predicates.md")
 (include "constraints.md")
   
@@ -112,6 +114,282 @@
 		       (const_int 2))]
         (const_int 2)))
 
+;; GJL
+(define_insn "*extract_bithiqi"
+  [(set (match_operand:QI 0 "register_operand" "=d,d,*r")
+        (subreg:QI (zero_extract:HI (match_operand:QI 1 "register_operand" "0,0,*r")
+                                    (const_int 1)
+                                    (match_operand:QI 2 "const_int_operand" "L,P,n")) 0))]
+  "(avr_test & 2) && INTVAL(operands[2]) > 1"
+  "@
+        andi %0,1
+        lsr %0\;andi %0,1
+        bst %1,%2\;clr %0\;bld %0,0"
+  [(set_attr "length" "1,2,3")
+   (set_attr "cc" "clobber,clobber,clobber")])
+
+(define_insn "*extract_bitqi"
+  [(set (match_operand:QI 0 "register_operand" "=d,d,*r")
+        (zero_extract:QI (match_operand:QI 1 "register_operand" "0,0,*r")
+                         (const_int 1)
+                         (match_operand:QI 2 "const_int_operand" "L,P,n")))]
+  "(avr_test & 2) && 0 && INTVAL(operands[2]) > 1"
+  "@
+        andi %0,1
+        lsr %0\;andi %0,1
+        bst %1,%2\;clr %0\;bld %0,0"
+  [(set_attr "length" "1,2,3")
+   (set_attr "cc" "clobber,clobber,clobber")])
+
+(define_insn "*extract_bithihi"
+  [(set (match_operand:HI 0 "register_operand" "=r")
+        (and:HI (lshiftrt:HI (match_operand:HI 1 "register_operand" "r")
+                             (match_operand:HI 2 "const_int_operand" "n"))
+                (const_int 1)))]
+  "(avr_test & 2) && (INTVAL (operands[2]) & 7) > 1"
+  {
+        return (INTVAL (operands[2]) >= 8) 
+                ? "bst %B1,%2-8\;clr %B0\;clr %A0\;bld %A0,0"
+                : "bst %A1,%2  \;clr %B0\;clr %A0\;bld %A0,0";
+  }
+  [(set_attr "length" "4")
+   (set_attr "cc" "clobber")])
+
+(define_insn "*extract_bitqihi"
+  [(set (match_operand:HI 0 "register_operand" "=r")
+        (zero_extract:HI (match_operand:QI 1 "register_operand" "r")
+                         (const_int 1)
+                         (match_operand:QI 2 "const_int_operand" "n")))]
+  "(avr_test & 2) && INTVAL(operands[2]) > 1"
+  "bst %1,%2\;clr %B0\;clr %A0\;bld %A0,0"
+  [(set_attr "length" "4")
+   (set_attr "cc" "clobber")])
+
+(define_insn "*extract_bit<mode>qi"
+  [(set (match_operand:QI 0 "register_operand" "=r")
+        (and:QI (subreg:QI (match_operator:HISI 1 "shiftrt_operator" 
+                                           [(match_operand:HISI 2 "register_operand" "r")
+                                            (match_operand:HISI 3 "const_int_operand" "n")]) 0)
+                (const_int 1)))]
+  "(avr_test & 2) && (<MODE>mode == SImode || (INTVAL(operands[3]) & 7) > 1)"
+  {
+        HOST_WIDE_INT bit = INTVAL (operands[3]);
+        if (bit >= 24)  return "bst %D2,%3-24\;clr %A0\;bld %A0,0";
+        if (bit >= 16)  return "bst %C2,%3-16\;clr %A0\;bld %A0,0";
+        if (bit >=  8)  return "bst %B2,%3-8 \;clr %A0\;bld %A0,0";
+        return                 "bst %A2,%3   \;clr %A0\;bld %A0,0";
+  }
+  [(set_attr "length" "3")
+   (set_attr "cc" "clobber")])
+
+(define_insn "*insert_bit<mode>qi"
+  [(set (match_operand:QI 0 "register_operand" "=r")
+        (and:QI (ashift:QI (subreg:QI (match_operator:HISI 1 "shiftrt_operator"
+                                                           [(match_operand:HISI 2 "register_operand" "r")
+                                                            (match_operand:HISI 3 "const_int_operand" "n")]) 0)
+                           (match_operand:QI 4 "const_int_operand" "n"))
+                (match_operand:QI 5 "single_one_operand" "n")))] ; = (1 << [4])
+  "(avr_test & 2) && INTVAL(operands[4]) == exact_log2(0xff & INTVAL(operands[5]))"
+  {
+      HOST_WIDE_INT from_bit = INTVAL(operands[3]);
+
+      if (from_bit >= 24) return "bst %D2,%3-24\;clr %0\;bld %0,%4";
+      if (from_bit >= 16) return "bst %C2,%3-16\;clr %0\;bld %0,%4";
+      if (from_bit >=  8) return "bst %B2,%3-8 \;clr %0\;bld %0,%4";
+      return "bst %A2,%3\;clr %0\;bld %0,%4";
+  }
+  [(set_attr "length" "3")
+   (set_attr "cc" "clobber")])
+
+(define_insn "*ashift_1_bit"
+  [(set (match_operand:QI 0 "register_operand" "=r")
+        (and:QI (ashift:QI (match_operand:QI 1 "register_operand" "r")
+                           (match_operand:QI 2 "const_int_operand" "n"))
+                (match_operand:QI 3 "single_one_operand" "n")))]
+  "(avr_test & 4) && exact_log2 (0xff & INTVAL(operands[3])) == INTVAL(operands[2])"
+  "bst %1,0\;clr %0\;bld %0,%2"
+  [(set_attr "length" "3")
+   (set_attr "cc" "clobber")])
+
+(define_insn "*insert_1_bit_ashift"
+  [(set (match_operand:QI 0 "register_operand" "=r")
+        (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
+                        (match_operand:QI 2 "single_zero_operand" "n")) ; = ~(1 << [4]) single_zero
+                (and:QI (ashift:QI (match_operand:QI 3 "register_operand" "r")
+                                   (match_operand:QI 4 "const_int_operand" "n"))
+                        (match_operand:QI 5 "single_one_operand" "n"))))] ; = (1 << [4])
+
+  "(avr_test & 8) 
+     && exact_log2(0xff & INTVAL(operands[5])) == INTVAL(operands[4]) 
+     && 0xff == (0xff & (INTVAL(operands[5]) ^ INTVAL(operands[2])))"
+  "bst %3,0\;bld %0,%4"
+  [(set_attr "length" "2")
+   (set_attr "cc" "none")])
+
+(define_insn "*insert_1_bit0"
+  [(set (match_operand:QI 0 "register_operand" "=r")
+        (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
+                        (match_operand:QI 2 "single_zero_operand" "n")) ; = ~[4]
+                (and:QI (match_operand:QI 3 "register_operand" "r")
+                        (match_operand:QI 4 "single_one_operand" "n"))))]
+  "(avr_test & 8) 
+     && 0xff == (0xff & (INTVAL(operands[4]) ^ INTVAL(operands[2])))"
+  {
+     operands[4] = GEN_INT(exact_log2(0xff & INTVAL(operands[4])));
+     return "bst %3,%4\;bld %0,%4";
+  }
+  [(set_attr "length" "2")
+   (set_attr "cc" "none")])
+
+;; special case of pattern below
+(define_insn "*iorqi2_ashift_bit7"
+  [(set (match_operand:QI 0 "register_operand" "=d,r")
+        (ior:QI (ashift:QI (match_operand:QI 1 "register_operand" "r,r")
+                           (const_int 7))
+                (match_operand:QI 2 "register_operand" "0,0")))]
+  "(avr_test & 16)"
+  "@
+	sbrc %1,0\;ori %0,0x80
+	bst %1,0\;sbrs %0,7\;bld %0,7"
+  [(set_attr "length" "2,3")
+   (set_attr "cc" "clobber,none")])
+
+(define_insn "*iorqi2_ashift_bit"
+  [(set (match_operand:QI 0 "register_operand" "=d,r")
+        (ior:QI (and:QI (ashift:QI (match_operand:QI 1 "register_operand" "r,r")
+                                   (match_operand:QI 2 "const_int_operand" "n,n"))
+                        (match_operand:QI 3 "single_one_operand" "n,n"))
+                (match_operand:QI 4 "register_operand" "0,0")))]
+  "(avr_test & 16)"
+  {
+      HOST_WIDE_INT to_bit = exact_log2 (0xff & INTVAL(operands[3]));
+      HOST_WIDE_INT from_bit = to_bit - INTVAL(operands[2]);
+
+      operands[2] = GEN_INT (from_bit);
+      operands[3] = GEN_INT (to_bit);
+
+      if (0 == which_alternative)
+          return "sbrc %1,%2\;ori %0,(1 << %3)";
+
+      return "bst %1,%2\;sbrs %0,%3\;bld %0,%3";
+  }
+  [(set_attr "length" "2,3")
+   (set_attr "cc" "clobber,none")])
+
+;; needs the above pattern as combiner bridge
+(define_insn "*movebit_ashift"
+  [(set (match_operand:QI 0 "register_operand" "=r")
+        (ior:QI (and:QI (ashift:QI (match_operand:QI 1 "register_operand" "r")
+                                   (match_operand:QI 2 "const_int_operand" "n"))
+                        (match_operand:QI 3 "single_one_operand" "n"))
+                (and:QI (match_operand:QI 4 "register_operand" "0")
+                        (match_operand:QI 5 "single_zero_operand" "n"))))] ; = ~[3]
+  "(avr_test & 16) 
+     && 0xff == (0xff & (INTVAL(operands[3]) ^ INTVAL(operands[5])))"
+  {
+      HOST_WIDE_INT to_bit = exact_log2 (0xff & INTVAL(operands[3]));
+      HOST_WIDE_INT from_bit = to_bit - INTVAL(operands[2]);
+
+      operands[2] = GEN_INT (from_bit);
+      operands[3] = GEN_INT (to_bit);
+      return "bst %1,%2\;bld %0,%3";
+  }
+  [(set_attr "length" "2")
+   (set_attr "cc" "none")])
+
+(define_insn "*iorqi2_shiftrt_bit"
+  [(set (match_operand:QI 0 "register_operand" "=d,r")
+        (ior:QI (and:QI (match_operator:QI 1 "shiftrt_operator"
+                                           [(match_operand:QI 2 "register_operand" "r,r")
+                                            (match_operand:QI 3 "const_int_operand" "n,n")])
+                        (match_operand:QI 4 "single_one_operand" "n,n"))
+                (match_operand:QI 5 "register_operand" "0,0")))]
+  "(avr_test & 32)"
+  {
+      HOST_WIDE_INT to_bit = exact_log2 (0xff & INTVAL(operands[4]));
+      HOST_WIDE_INT from_bit = to_bit + INTVAL(operands[3]);
+
+      operands[3] = GEN_INT (from_bit);
+      operands[4] = GEN_INT (to_bit);
+
+      if (0 == which_alternative)
+          return "sbrc %2,%3\;ori %0,(1 << %4)";
+
+      return "bst %2,%3\;sbrs %0,%4\;bld %0,%4";
+  }
+  [(set_attr "length" "2,3")
+   (set_attr "cc" "clobber,none")])
+
+;; needs the above pattern as combiner bridge
+(define_insn "*movebit_shiftrt"
+  [(set (match_operand:QI 0 "register_operand" "=r")
+        (ior:QI (and:QI (match_operator:QI 1 "shiftrt_operator"
+                                           [(match_operand:QI 2 "register_operand" "r")
+                                            (match_operand:QI 3 "const_int_operand" "n")])
+                        (match_operand:QI 4 "single_one_operand" "n"))
+                (and:QI (match_operand:QI 5 "register_operand" "0")
+                        (match_operand:QI 6 "single_zero_operand" "n"))))] ; = ~[4]
+  "(avr_test & 32) 
+     && 0xff == (0xff & (INTVAL(operands[4]) ^ INTVAL(operands[6])))"
+  {
+      HOST_WIDE_INT to_bit = exact_log2 (0xff & INTVAL(operands[4]));
+      HOST_WIDE_INT from_bit = to_bit + INTVAL(operands[3]);
+
+      operands[3] = GEN_INT (from_bit);
+      operands[4] = GEN_INT (to_bit);
+      return "bst %2,%3\;bld %0,%4";
+  }
+  [(set_attr "length" "2")
+   (set_attr "cc" "none")])
+
+;; same as above, for .0 <- .7
+(define_insn "*movebit_shiftrt_7"
+  [(set (match_operand:QI 0 "register_operand" "=r")
+        (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
+                        (match_operand:QI 2 "single_zero_operand" "n")) ; ~1
+                (match_operator:QI 3 "shiftrt_operator"
+                                   [(match_operand:QI 4 "register_operand" "r")
+                                    (const_int 7)])))]
+  "(avr_test & 32) && 0xfe == (0xff & INTVAL(operands[2]))" 
+  "bst %4,7\;bld %0,0"
+  [(set_attr "length" "2")
+   (set_attr "cc" "none")])
+
+;; same as above, for .7 <- .0
+(define_insn "*movebit_ashift_7"
+  [(set (match_operand:QI 0 "register_operand" "=r")
+        (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
+                        (match_operand:QI 2 "single_zero_operand" "n")) ; 0x7f
+                (ashift:QI (match_operand:QI 3 "register_operand" "r")
+                           (const_int 7))))]
+  "(avr_test & 16) && 0x7f == (0xff & INTVAL(operands[2]))" 
+  "bst %3,0\;bld %0,7"
+  [(set_attr "length" "2")
+   (set_attr "cc" "none")])
+
+;; swap
+(define_insn "*swap_nibbles"
+  [(set (match_operand:QI 0 "register_operand" "=r")
+        (rotate:QI (match_operand:QI 1 "register_operand" "0")
+                   (const_int 4)))]
+  "(avr_test & 64)"
+  "swap %0"
+  [(set_attr "length" "1")
+   (set_attr "cc" "none")])
+
+(define_insn "*zero_extendqihi2_bit"
+  [(set (match_operand:HI 0 "register_operand" "=d,*r")
+        (zero_extend:HI (zero_extract:QI (match_operand:QI 1 "register_operand" "0,r")
+                                         (const_int 1)
+                                         (match_operand:QI 2 "const_int_operand" "P,n"))))]
+  "(avr_test & 2) && INTVAL (operands[2]) > 0"
+  "@
+        lsr %A0\;andi %A0,1\;clr %B0        
+        bst %A1,%2\;clr %A0\;bld %A0,0\;clr %B0"
+  [(set_attr "length" "3,4")
+   (set_attr "cc" "clobber,clobber")])
+; /GJL
+
 (define_insn "*pushqi"
   [(set (mem:QI (post_dec (reg:HI REG_SP)))
         (match_operand:QI 0 "reg_or_0_operand" "r,L"))]
@@ -2061,6 +2339,30 @@
 				    (const_int 4))))
    (set_attr "cc" "clobber")])
 
+;; same as above
+(define_insn "*sbrx_branch_shiftrt<mode>"
+  [(set (pc)
+        (if_then_else
+         (match_operator 0 "eqne_operator"
+                         [(zero_extract (match_operator 4 "shiftrt_operator"
+                                                        [(match_operand:QIHISI 1 "register_operand" "r")
+                                                         (match_operand 2 "const_int_operand" "n")])
+                                        (const_int 1)
+                                        (const_int 0))
+                          (const_int 0)])
+         (label_ref (match_operand 3 "" ""))
+         (pc)))]
+  "(avr_test & 64)"
+  "* 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")])
+
 (define_insn "*sbrx_and_branchhi"
   [(set (pc)
         (if_then_else
@@ -2516,6 +2818,31 @@
 				    (const_int 4))))
    (set_attr "cc" "clobber")])
 
+;; GJL
+;; same as above, needed because rtx was not canonicalised
+(define_insn "*sbix_branch_shiftrt"
+  [(set (pc)
+        (if_then_else
+         (match_operator 0 "eqne_operator"
+                         [(zero_extract (match_operator 4 "shiftrt_operator"
+                                                        [(mem:QI (match_operand 1 "low_io_address_operand" "n"))
+                                                         (match_operand 2 "const_int_operand" "n")])
+                                        (const_int 1)
+                                        (const_int 0))
+                          (const_int 0)])
+         (label_ref (match_operand 3 "" ""))
+         (pc)))]
+  "(optimize > 0) && (avr_test & 64)"
+  "* 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")])
+
 ;; Tests of bit 7 are pessimized to sign tests, so we need this too...
 (define_insn "*sbix_branch_bit7"
   [(set (pc)
Index: gcc/config/avr/avr.opt
===================================================================
--- gcc/config/avr/avr.opt	(revision 142396)
+++ gcc/config/avr/avr.opt	(working copy)
@@ -66,3 +66,6 @@ Relax branches
 mpmem-wrap-around
 Target Report
 Make the linker relaxation machine assume that a program counter wrap-around occures.
+
+mtest=
+Target RejectNegative Report Joined Undocumented UInteger Var(avr_test) Init(0)
