--- gcc/config/rx/constraints.md	2012-10-17 15:37:53.000000000 +0530
+++ gcc/config/rx/constraints.md	2012-11-07 09:28:40.000000000 +0530
@@ -141,3 +141,42 @@
        )
   )
 )
+
+(define_constraint "Uint03"
+  "An unsigned 3-bit constant, as used in bclr, bset, etc."
+  (and (match_code "const_int")
+       (match_test "ival >= 0 && ival <= 7")))
+  
+(define_constraint "Intu1"
+  "Integer constant 1."
+  (and (match_code "const_int")
+       (match_test "ival == 1")))
+
+(define_constraint "Intu0"
+  "Integer constant 0."
+  (and (match_code "const_int")
+       (match_test "ival == 0")))
+
+(define_constraint "Intsz"
+  "Integer constant with a single zero bit in the lower 8-bit."
+  (and (match_code "const_int")
+       (ior (match_test "~ival == 1")
+	    (match_test "~ival == 2")
+	    (match_test "~ival == 4")
+	    (match_test "~ival == 8")
+	    (match_test "~ival == 16")
+	    (match_test "~ival == 32")
+	    (match_test "~ival == 64")
+	    (match_test "~ival == 128"))))
+
+(define_constraint "Intso"
+  "Integer constant with a single bit set in its lower 8-bit."
+  (and (match_code "const_int")
+       (ior (match_test "ival == 1")
+	    (match_test "ival == 2")
+	    (match_test "ival == 4")
+	    (match_test "ival == 8")
+	    (match_test "ival == 16")
+	    (match_test "ival == 32")
+	    (match_test "ival == 64")
+	    (match_test "ival == 128"))))
--- gcc/config/rx/predicates.md	2012-10-17 16:55:36.000000000 +0530
+++ gcc/config/rx/predicates.md	2012-11-07 09:28:40.000000000 +0530
@@ -47,6 +47,11 @@
        (match_test "IN_RANGE (INTVAL (op), 0, 31)"))
 )
 
+(define_predicate "rx_constbit_operand"
+  (and (match_code "const_int")
+       (match_test "IN_RANGE (INTVAL (op), 0, 7)"))
+)
+
 (define_predicate "rx_restricted_mem_operand"
   (and (match_code "mem")
        (match_test "rx_is_restricted_memory_address (XEXP (op, 0), mode)"))
--- gcc/config/rx/rx.c	2012-10-25 13:57:43.000000000 +0530
+++ gcc/config/rx/rx.c	2012-11-07 09:28:40.000000000 +0530
@@ -500,6 +500,8 @@ rx_assemble_integer (rtx x, unsigned int
      %A  Print an operand without a leading # character.
      %B  Print an integer comparison name.
      %C  Print a control register name.
+     %D  Print the position of a single bit set.
+     %E  Print the position of a single bit cleared.
      %F  Print a condition code flag name.
      %G  Register used for small-data-area addressing
      %H  Print high part of a DImode register, integer or address.
@@ -648,6 +650,22 @@ rx_print_operand (FILE * file, rtx op, i
 	}
       break;
 
+    case 'D':
+      {
+	int num = exact_log2 (INTVAL (op));
+	gcc_assert (num >= 0);
+	fprintf (file, "#%d", num);
+      }
+      break;
+      
+    case 'E':
+      {
+	int num = exact_log2 (~INTVAL (op));
+	gcc_assert (num >= 0);
+	fprintf (file, "#%d", num);
+      }
+      break;
+
     case 'F':
       gcc_assert (CONST_INT_P (op));
       switch (INTVAL (op))
--- gcc/config/rx/rx.md	2012-10-29 12:18:35.000000000 +0530
+++ gcc/config/rx/rx.md	2012-11-08 10:05:11.000000000 +0530
@@ -2781,6 +2781,35 @@
 ;; bit offset, so that we can adjust the address by ofs/8 and replace
 ;; the offset in the insn by ofs%8.
 
+(define_insn "*iorbset_mem"
+  [(set (match_operand:QI 0 "rx_restricted_mem_operand" "+Q")
+	(ior:QI (match_dup 0)
+		(match_operand 1 "const_int_operand" "Intso")))]
+  "satisfies_constraint_Intso (operands[1])"
+  "bset\\t%D1,%0.B"
+  [(set_attr "length" "3")]
+)
+                
+(define_insn "*iorbset_reg"
+  [(set (match_operand:SI 0 "register_operand" "+r")
+	(ior:SI (match_dup 0)
+		(match_operand 1 "const_int_operand" "Intso")))]
+  "satisfies_constraint_Intso (operands[1])"
+  "bset\\t%D1,%0"
+  [(set_attr "length" "3")]
+)
+
+(define_insn "*bset"
+  [(set (zero_extract:SI 
+	  (match_operand:QI 0 "rx_restricted_mem_operand" "+Q")
+	  (const_int 1)
+	  (match_operand 1 "rx_constbit_operand" "Uint03"))
+	(const_int 1))]
+  ""
+  "bset\\t%1,%0.B"
+  [(set_attr "length" "3")]
+)
+
 (define_insn "*bitset"
   [(set (match_operand:SI                    0 "register_operand" "=r")
 	(ior:SI (ashift:SI (const_int 1)
@@ -2791,7 +2820,7 @@
   [(set_attr "length" "3")]
 )
 
-(define_insn "*bitset_in_memory"
+(define_insn "bitset_in_memory"
   [(set (match_operand:QI                    0 "rx_restricted_mem_operand" "+Q")
 	(ior:QI (ashift:QI (const_int 1)
 			   (match_operand:QI 1 "nonmemory_operand" "ri"))
@@ -2802,6 +2831,24 @@
    (set_attr "timings" "33")]
 )
 
+(define_insn "*xorbnot_mem"
+  [(set (match_operand:QI 0 "rx_restricted_mem_operand" "+Q")
+	(xor:QI (match_dup 0)
+		(match_operand 1 "const_int_operand" "Intso")))]
+  "satisfies_constraint_Intso (operands[1])"
+  "bnot\\t%D1,%0.B"
+  [(set_attr "length" "3")]
+)
+
+(define_insn "*xorbnot_reg"
+  [(set (match_operand:SI 0 "register_operand" "+r")
+	(xor:SI (match_dup 0)
+		(match_operand 1 "const_int_operand" "Intso")))]
+  "satisfies_constraint_Intso (operands[1])"
+  "bnot\\t%D1,%0"
+  [(set_attr "length" "3")]
+)
+
 (define_insn "*bitinvert"
   [(set (match_operand:SI 0 "register_operand" "=r")
 	(xor:SI (ashift:SI (const_int 1)
@@ -2823,6 +2870,35 @@
    (set_attr "timings" "33")]
 )
 
+(define_insn "*andbclr_mem"
+  [(set (match_operand:QI 0 "rx_restricted_mem_operand" "+Q")
+	(and:QI (match_dup 0)
+		(match_operand 1 "const_int_operand" "Intsz")))]
+  "satisfies_constraint_Intsz (operands[1])"
+  "bclr\\t%E1,%0.B"
+  [(set_attr "length" "3")]
+)
+
+(define_insn "*andbclr_reg"
+  [(set (match_operand:SI 0 "register_operand" "+r")
+	(and:SI (match_dup 0)
+		(match_operand 1 "const_int_operand" "Intsz")))]
+  "satisfies_constraint_Intsz (operands[1])"
+  "bclr\\t%E1,%0"
+  [(set_attr "length" "3")]
+)
+
+(define_insn "*bclr"
+  [(set (zero_extract:SI
+	  (match_operand:QI 0 "rx_restricted_mem_operand" "+Q")
+	  (const_int 1)
+	  (match_operand 1 "rx_constbit_operand" "Uint03"))
+	(const_int 0))]
+  ""
+  "bclr\\t%1,%0.B"
+  [(set_attr "length" "3")]
+)
+
 (define_insn "*bitclr"
   [(set (match_operand:SI 0 "register_operand" "=r")
 	(and:SI (not:SI
@@ -2835,7 +2911,7 @@
   [(set_attr "length" "3")]
 )
 
-(define_insn "*bitclr_in_memory"
+(define_insn "bitclr_in_memory"
   [(set (match_operand:QI 0 "rx_restricted_mem_operand" "+Q")
 	(and:QI (not:QI
 		  (ashift:QI
@@ -2848,6 +2924,22 @@
    (set_attr "timings" "33")]
 )
 
+(define_insn "*insv_mem_imm"
+  [(set (zero_extract:SI
+	  (match_operand 0 "rx_restricted_mem_operand" "+Q")
+	  (const_int 1)
+	  (match_operand 1 "nonmemory_operand" "ri"))
+	(match_dup 0))]
+  ""
+{
+  if (INTVAL (operands[2]) & 1)
+    return "bset\t%1, %0.B";
+  else
+    return "bclr\t%1, %0.B";
+}
+  [(set_attr "length" "3")]
+)
+
 (define_insn "*insv_imm"
   [(set (zero_extract:SI
 	  (match_operand:SI 0 "register_operand" "+r")
@@ -2975,16 +3067,37 @@
 
 (define_expand "insv"
   [(set (zero_extract:SI
-	  (match_operand:SI 0 "register_operand")	;; Destination
-	  (match_operand:SI 1 "const_int_operand")	;; # of bits to set
-	  (match_operand:SI 2 "nonmemory_operand"))	;; Starting bit
-	(match_operand:SI   3 "nonmemory_operand"))]	;; Bits to insert
+	  (match_operand 0 "nonimmediate_operand")	;; Destination
+	  (match_operand 1 "immediate_operand")		;; # of bits to set
+	  (match_operand 2 "const_int_operand"))	;; Starting bit
+	(match_operand   3 "nonmemory_operand"))]	;; Bits to insert
   ""
 {
   /* We only handle single-bit inserts.  */
   if (!CONST_INT_P (operands[1]) || INTVAL (operands[1]) != 1)
     FAIL;
 
+ if (GET_CODE (operands [0]) == MEM
+     && (!CONST_INT_P (operands[2])
+     || !CONST_INT_P (operands[3])
+     || (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) > 7)))
+   FAIL;
+
+ if (GET_CODE (operands [0]) == MEM
+      && satisfies_constraint_Intu1 (operands[1])
+      && satisfies_constraint_Uint03 (operands[2]))
+    {
+      if (satisfies_constraint_Intu0 (operands[3]))
+	{
+	  emit_insn (gen_bitclr_in_memory (operands[0], operands[1]));
+	  DONE;
+	}
+      else if (satisfies_constraint_Intu1 (operands[3]))
+	{
+	  emit_insn (gen_bitset_in_memory (operands[0], operands[2]));
+	  DONE;
+	}
+    }
   /* Either the bit to insert or the position must be constant.  */
   if (CONST_INT_P (operands[3]))
     operands[3] = GEN_INT (INTVAL (operands[3]) & 1);
