public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: [PATCH,SH] Add SH2A new instructions 6/6
@ 2007-10-25 13:53 Naveen H.S.
  2007-10-28 10:46 ` Kaz Kojima
  0 siblings, 1 reply; 14+ messages in thread
From: Naveen H.S. @ 2007-10-25 13:53 UTC (permalink / raw)
  To: Kaz Kojima; +Cc: gcc-patches, Anil Paranjape, Prafulla Thakare

[-- Attachment #1: Type: text/plain, Size: 2230 bytes --]

Hi,

Thank you for all the valuable suggestions and modifying the patch. We
will 
take care of all the comments and suggestions in our future works as
well. 
These bit instructions were implemented prior to the patch which
modified 
the bit patterns. This patch was posted in the following link
http://gcc.gnu.org/ml/gcc-patches/2007-07/msg01531.html

The implemented bit instructions resulted in very good optimization of
the 
bit operations. However, the bit instructions are not getting generated
more 
frequently after the above mentioned patch. Please suggest the
modifications 
to be done on the present patch to generate bit instructions as earlier.

Please find attached the modified patch "sh2a6.patch" as per the
suggestions. 

ChangeLog
2007-10-25	Naveen.H.S naveen.hs@kpitcummins.com

	* config/sh/constraints.md: K03, K12, Sbw : New constraints.
	* config/sh/predicates.md (bitwise_memory_operand) : New
predicate.
	* config/sh/sh.c (print_operand): "f" bit operator
	"e" bitnot operator.
	"t" prints memory address of a register.
	* config/sh/sh.h (sh_args): Add condition for SH2A.
	* config/sh/sh.md (extendqisi2_compact): enable 4-byte mov.b 
	instructions.
	(extendqihi2): enable 4-byte mov.b instructions.
	(movqi_i): enable 4-byte mov.b instructions.
	(insv): Add conditions to generate BSET, BCLR and BST
instructions in 
	memory mode.
	(extv): Add conditions to generate BLD instruction in memory
mode.
	(extzv): Add conditions to generate BLD instruction in memory
mode.
	bclr_m2a, bset_m2a, bst_m2a, bld_m2a, bld_reg, *bld_regqi,
bld_reg1, 
	bld_regqi1, bldnot_m2a, band_m2a, bandnot_m2a, bor_m2a,
bornot_m2a, 
	bxor_m2a, bit_m2a, bitnot_m2a: New instructions.
	
Regards,
Naveen.H.S.
KPIT Cummins Infosystems Ltd,
Pune (INDIA) 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~	
Free download of GNU based tool-chains for Renesas' SH, H8, R8C, M16C	
and M32C Series. The following site also offers free technical support	
to its users. Visit http://www.kpitgnutools.com for details. 	
Latest versions of KPIT GNU tools were released on October 1, 2007.	
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~	

[-- Attachment #2: sh2a6.patch --]
[-- Type: application/octet-stream, Size: 29748 bytes --]

diff -upr gcc-4.3-20070921/gcc/config/sh/constraints.md tars/gcc-4.3-20070921/gcc/config/sh/constraints.md
--- gcc-4.3-20070921/gcc/config/sh/constraints.md	2007-10-24 12:21:48.000000000 +0530
+++ tars/gcc-4.3-20070921/gcc/config/sh/constraints.md	2007-10-24 12:26:33.000000000 +0530
@@ -125,11 +125,21 @@
   (and (match_code "const_int")
        (match_test "CONST_OK_FOR_J16 (ival)")))
 
+(define_constraint "K03"
+  "An unsigned 3-bit constant, as used in SH2A bclr, bset, etc."
+  (and (match_code "const_int")
+       (match_test "ival >= 0 && ival <= 7")))
+
 (define_constraint "K08"
   "An unsigned 8-bit constant, as used in and, or, etc."
   (and (match_code "const_int")
        (match_test "ival >= 0 && ival <= 255")))
  
+(define_constraint "K12"
+  "An unsigned 8-bit constant, as used in SH2A 12-bit display."
+  (and (match_code "const_int")
+       (match_test "ival >= 0 && ival <= 4095")))
+
 (define_constraint "K16"
   "An unsigned 16-bit constant, as used in SHmedia shori."
   (and (match_code "const_int")
@@ -239,3 +249,10 @@
   "@internal"
   (and (match_test "memory_operand (op, GET_MODE (op))")
        (match_test "GET_CODE (XEXP (op, 0)) != PLUS")))
+
+(define_memory_constraint "Sbw"
+  "A memory reference, as used in SH2A bclr.b, bset.b, etc."
+  (and (match_test "MEM_P (op) && GET_MODE (op) == QImode")
+       (match_test "GET_CODE (XEXP (op, 0)) == PLUS")
+       (match_test "REG_P (XEXP (XEXP (op, 0), 0))")
+       (match_test "satisfies_constraint_K12 (XEXP (XEXP (op, 0), 1))")))
diff -upr gcc-4.3-20070921/gcc/config/sh/predicates.md tars/gcc-4.3-20070921/gcc/config/sh/predicates.md
--- gcc-4.3-20070921/gcc/config/sh/predicates.md	2007-08-02 16:19:31.000000000 +0530
+++ tars/gcc-4.3-20070921/gcc/config/sh/predicates.md	2007-10-24 12:51:53.000000000 +0530
@@ -516,6 +516,11 @@
 (define_predicate "logical_operator"
   (match_code "and,ior,xor"))
 
+;; Recognize valid operators for bitnot instructions.
+
+(define_predicate "andor_operator"
+  (match_code "and,ior"))
+
 ;; Like arith_reg_operand, but for register source operands of narrow
 ;; logical SHMEDIA operations: forbid subregs of DImode / TImode regs.
 
@@ -789,3 +794,19 @@
     return 0;
   return arith_reg_operand (op, mode);
 })
+
+(define_predicate "bitwise_memory_operand"
+  (match_code "mem")
+{
+  if (GET_CODE (op) == MEM)
+    {
+      if (REG_P (XEXP (op, 0)))
+	return 1;
+
+      if (GET_CODE (XEXP (op, 0)) == PLUS
+	  && GET_CODE (XEXP (XEXP (op, 0), 0)) == REG
+	  && satisfies_constraint_K12 (XEXP (XEXP (op, 0), 1)))
+        return 1;
+    }
+  return 0;
+})
diff -upr gcc-4.3-20070921/gcc/config/sh/sh.c tars/gcc-4.3-20070921/gcc/config/sh/sh.c
--- gcc-4.3-20070921/gcc/config/sh/sh.c	2007-10-24 12:21:48.000000000 +0530
+++ tars/gcc-4.3-20070921/gcc/config/sh/sh.c	2007-10-24 12:26:33.000000000 +0530
@@ -678,6 +678,9 @@ print_operand_address (FILE *stream, rtx
    'U'  Likewise for {LD,ST}{HI,LO}.
    'V'  print the position of a single bit set.
    'W'  print the position of a single bit cleared.
+   'f'  output the bit operator.
+   'e'  output the bitnot operator.
+   't'  print a memory address which is a register.
    'u'  prints the lowest 16 bits of CONST_INT, as an unsigned value.
    'o'  output an operator.  */
 
@@ -818,6 +821,52 @@ print_operand (FILE *stream, rtx x, int 
 	  break;
 	}
       break;
+
+    case 'f':
+      switch (GET_CODE (x))
+        {
+        case IOR:
+          fprintf (stream, "or");
+          break;
+        case XOR:
+          fprintf (stream, "xor");
+          break;
+        case AND:
+          fprintf (stream, "and");
+          break;
+        default:
+          break;
+        }
+      break;
+
+    case 'e':
+      switch (GET_CODE (x))
+        {
+        case IOR:
+          fprintf (stream, "ornot");
+          break;
+        case AND:
+          fprintf (stream, "andnot");
+          break;
+        default:
+          break;
+        }
+      break;
+
+    case 't':
+      gcc_assert (GET_CODE (x) == MEM);
+      x = XEXP (x, 0);
+      switch (GET_CODE (x))
+	{
+	case REG:
+	case SUBREG:
+	  print_operand (stream, x, 0);
+	  break;
+	default:
+	  break;
+	}
+      break;
+
     case 'o':
       switch (GET_CODE (x))
 	{
diff -upr gcc-4.3-20070921/gcc/config/sh/sh.h tars/gcc-4.3-20070921/gcc/config/sh/sh.h
--- gcc-4.3-20070921/gcc/config/sh/sh.h	2007-09-12 12:29:06.000000000 +0530
+++ tars/gcc-4.3-20070921/gcc/config/sh/sh.h	2007-10-24 12:26:33.000000000 +0530
@@ -2459,6 +2459,12 @@ struct sh_args {
 	    else							\
 	      break;							\
 	  }								\
+	if (TARGET_SH2A)						\
+	  {								\
+	    if (GET_MODE_SIZE (MODE) == 1				\
+		&& (unsigned) INTVAL (OP) < 4096)			\
+	    goto LABEL;							\
+	  }								\
 	if (MODE_DISP_OK_4 ((OP), (MODE)))  goto LABEL;		      	\
 	if (MODE_DISP_OK_8 ((OP), (MODE)))  goto LABEL;		      	\
       }									\
diff -upr gcc-4.3-20070921/gcc/config/sh/sh.md tars/gcc-4.3-20070921/gcc/config/sh/sh.md
--- gcc-4.3-20070921/gcc/config/sh/sh.md	2007-10-24 12:21:48.000000000 +0530
+++ tars/gcc-4.3-20070921/gcc/config/sh/sh.md	2007-10-24 12:48:56.000000000 +0530
@@ -4726,7 +4726,12 @@ label:
   "@
 	exts.b	%1,%0
 	mov.b	%1,%0"
-  [(set_attr "type" "arith,load")])
+  [(set_attr "type" "arith,load")
+   (set_attr_alternative "length"
+     [(const_int 2)
+       (if_then_else
+	(ne (symbol_ref "TARGET_SH2A") (const_int 0))
+	(const_int 4) (const_int 2))])])
 
 (define_insn "*extendqisi2_media"
   [(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -4764,7 +4769,12 @@ label:
   "@
 	exts.b	%1,%0
 	mov.b	%1,%0"
-  [(set_attr "type" "arith,load")])
+  [(set_attr "type" "arith,load")
+   (set_attr_alternative "length"
+     [(const_int 2)
+       (if_then_else
+	(ne (symbol_ref "TARGET_SH2A") (const_int 0))
+	(const_int 4) (const_int 2))])])
 
 /* It would seem useful to combine the truncXi patterns into the movXi
    patterns, but unary operators are ignored when matching constraints,
@@ -5312,7 +5322,19 @@ label:
 	movt	%0
 	sts	%1,%0
 	lds	%1,%0"
- [(set_attr "type" "move,movi8,load,store,arith,prget,prset")])
+ [(set_attr "type" "move,movi8,load,store,arith,prget,prset")
+  (set_attr_alternative "length"
+     [(const_int 2)
+      (const_int 2)
+      (if_then_else
+	(ne (symbol_ref "TARGET_SH2A") (const_int 0))
+	(const_int 4) (const_int 2))
+      (if_then_else
+	(ne (symbol_ref "TARGET_SH2A") (const_int 0))
+	(const_int 4) (const_int 2))
+      (const_int 2)
+      (const_int 2)
+      (const_int 2)])])
 
 (define_insn "*movqi_media"
   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
@@ -11642,6 +11664,34 @@ mov.l\\t1f,r0\\n\\
   HOST_WIDE_INT bitsize, size, v = 0;
   rtx x = operands[3];
 
+  if (TARGET_SH2A
+      && satisfies_constraint_M (operands[1])
+      && satisfies_constraint_K03 (operands[2]))
+    {
+      if (satisfies_constraint_N (operands[3]))
+	{
+	  emit_insn (gen_bclr_m2a (operands[0], operands[2]));
+	  DONE;
+	}
+      else if (satisfies_constraint_M (operands[3]))
+	{
+	  emit_insn (gen_bset_m2a (operands[0], operands[2]));
+	  DONE;
+	}
+      else if ((REG_P (operands[3]) && REGNO (operands[3]) == T_REG)
+	       && satisfies_constraint_M (operands[1]))
+	{
+	  emit_insn (gen_bst_m2a (operands[0], operands[2]));
+	  DONE;
+	}
+      else if (REG_P (operands[3])
+	       && satisfies_constraint_M (operands[1]))
+	{
+	  emit_insn (gen_bld_reg (operands[3], const0_rtx));
+	  emit_insn (gen_bst_m2a (operands[0], operands[2]));
+	  DONE;
+	}
+    }
   /* ??? expmed doesn't care for non-register predicates.  */
   if (! memory_operand (operands[0], VOIDmode)
       || ! immediate_operand (operands[1], VOIDmode)
@@ -11719,8 +11769,17 @@ mov.l\\t1f,r0\\n\\
 	(sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
 			 (match_operand 2 "const_int_operand" "")
 			 (match_operand 3 "const_int_operand" "")))]
-  "TARGET_SH4A_ARCH"
+  "TARGET_SH4A_ARCH || TARGET_SH2A"
 {
+  if (TARGET_SH2A
+      && satisfies_constraint_M (operands[2])
+      && satisfies_constraint_K03 (operands[3])
+      && REGNO (operands[0]) == T_REG)
+   {
+      emit_insn (gen_bldsign_m2a (operands[1], operands[3]));
+      DONE;
+   }
+
   if (TARGET_SH4A_ARCH
       && INTVAL (operands[2]) == 32
       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
@@ -11740,8 +11799,18 @@ mov.l\\t1f,r0\\n\\
 	(zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
 			 (match_operand 2 "const_int_operand" "")
 			 (match_operand 3 "const_int_operand" "")))]
-  "TARGET_SH4A_ARCH"
+  "TARGET_SH4A_ARCH || TARGET_SH2A"
 {
+  if (TARGET_SH2A
+      && satisfies_constraint_M (operands[2])
+      && satisfies_constraint_K03 (operands[3]))
+    {
+      emit_insn (gen_bld_m2a (operands[1], operands[3]));
+      if (REGNO (operands[0]) != T_REG)
+	emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
+      DONE;
+    }
+
   if (TARGET_SH4A_ARCH
       && INTVAL (operands[2]) == 32
       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
@@ -11756,6 +11825,223 @@ mov.l\\t1f,r0\\n\\
   FAIL;
 })
 
+;; SH2A instructions for bitwise operations.
+
+;; Clear a bit in a memory location.
+(define_insn "bclr_m2a"
+  [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,m")
+        (and:QI
+            (not:QI (ashift:QI (const_int 1)
+                    (match_operand:QI 1 "const_int_operand" "K03,K03")))
+            (match_dup 0)))]
+  "TARGET_SH2A"
+  "@
+        bclr.b\\t%1,%0
+        bclr.b\\t%1,@(0,%t0)"
+ [(set_attr "length" "4,4")])
+
+;; Set a bit in a memory location.
+(define_insn "bset_m2a"
+  [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,m")
+        (ior:QI
+            (ashift:QI (const_int 1)
+                       (match_operand:QI 1 "const_int_operand" "K03,K03"))
+            (match_dup 0)))]
+  "TARGET_SH2A"
+  "@
+        bset.b\\t%1,%0
+        bset.b\\t%1,@(0,%t0)"
+  [(set_attr "length" "4")])
+
+;;; Transfer the contents of the T bit to a specified bit of memory.
+(define_insn "bst_m2a"
+  [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,m")
+        (if_then_else (eq (reg:SI T_REG) (const_int 0))
+            (and:QI
+                (not:QI (ashift:QI (const_int 1)
+                        (match_operand:QI 1 "const_int_operand" "K03,K03")))
+                (match_dup 0))
+            (ior:QI
+                (ashift:QI (const_int 1) (match_dup 1))
+                (match_dup 0))))]
+  "TARGET_SH2A"
+  "@
+        bst.b\\t%1,%0
+        bst.b\\t%1,@(0,%t0)"
+  [(set_attr "length" "4")])
+
+;; Store a specified bit of memory in the T bit.
+(define_insn "bld_m2a"
+  [(set (reg:SI T_REG)
+        (zero_extract:SI
+            (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
+            (const_int 1)
+            (match_operand 1 "const_int_operand" "K03,K03")))]
+  "TARGET_SH2A"
+  "@
+	bld.b\\t%1,%0
+	bld.b\\t%1,@(0,%t0)"
+  [(set_attr "length" "4,4")])
+
+;; Store a specified bit of memory in the T bit.
+(define_insn "bldsign_m2a"
+  [(set (reg:SI T_REG)
+        (sign_extract:SI
+            (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
+            (const_int 1)
+            (match_operand 1 "const_int_operand" "K03,K03")))]
+  "TARGET_SH2A"
+  "@
+        bld.b\\t%1,%0
+        bld.b\\t%1,@(0,%t0)"
+  [(set_attr "length" "4,4")])
+
+;; Store a specified bit of the LSB 8 bits of a register in the T bit.
+(define_insn "bld_reg"
+  [(set (reg:SI T_REG)
+        (zero_extract:SI (match_operand:SI 0 "arith_reg_operand" "r")
+                         (const_int 1)
+                         (match_operand 1 "const_int_operand" "K03")))]
+  "TARGET_SH2A"
+  "bld\\t%1,%0")
+
+(define_insn "*bld_regqi"
+  [(set (reg:SI T_REG)
+        (zero_extract:SI (match_operand:QI 0 "arith_reg_operand" "r")
+                         (const_int 1)
+                         (match_operand 1 "const_int_operand" "K03")))]
+  "TARGET_SH2A"
+  "bld\\t%1,%0")
+
+;; Store a specified bit of the LSB 8 bits of a register in the register.
+(define_insn "bld_genreg"
+  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
+        (zero_extract:SI (match_operand:SI 1 "arith_reg_operand" "r")
+                         (const_int 1)
+                         (match_operand 2 "const_int_operand" "K03")))]
+  "TARGET_SH2A"
+  "bld\\t%2,%1\;movt\\t%0")
+
+(define_insn "*bld_genregqi"
+  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
+        (zero_extract:SI (match_operand:QI 1 "arith_reg_operand" "r")
+                         (const_int 1)
+                         (match_operand 2 "const_int_operand" "K03")))]
+  "TARGET_SH2A"
+  "bld\\t%2,%1\;movt\\t%0")
+
+;; Store logical inverse of a specified bit of memory in the T bit.
+(define_insn "bldnot_m2a"
+  [(set (reg:SI T_REG)
+        (not:SI (zero_extract:SI
+            (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
+            (const_int 1)
+            (match_operand 1 "const_int_operand" "K03,K03"))))]
+  "TARGET_SH2A"
+  "@
+	bldnot.b\\t%1,%0
+	bldnot.b\\t%1,@(0,%t0)"
+  [(set_attr "length" "4,4")])
+
+;; Take logical and of a specified bit of memory with the T bit and
+;; store its result in the T bit.
+(define_insn "band_m2a"
+  [(set (reg:SI T_REG)
+        (and:SI (reg:SI T_REG)
+                (zero_extract:SI
+                    (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
+                    (const_int 1)
+                    (match_operand 1 "const_int_operand" "K03,K03"))))]
+  "TARGET_SH2A"
+  "@
+	band.b\\t%1,%0
+	band.b\\t%1,@(0,%t0)"
+  [(set_attr "length" "4,4")])
+
+;; Take logical and of logical inverse of a specified bit of memory
+;; with the T bit and store its result in the T bit.
+(define_insn "bandnot_m2a"
+  [(set (reg:SI T_REG)
+        (and:SI (reg:SI T_REG)
+                (not:SI (zero_extract:SI
+                    (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
+                    (const_int 1)
+                    (match_operand 1 "const_int_operand" "K03,K03")))))]
+  "TARGET_SH2A"
+  "@
+	bandnot.b\\t%1,%0
+	bandnot.b\\t%1,@(0,%t0)"
+  [(set_attr "length" "4,4")])
+
+;; Take logical or of a specified bit of memory with the T bit and
+;; store its result in the T bit.
+(define_insn "bor_m2a"
+  [(set (reg:SI T_REG)
+        (ior:SI (reg:SI T_REG)
+                (zero_extract:SI
+                    (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
+                    (const_int 1)
+                    (match_operand 1 "const_int_operand" "K03,K03"))))]
+  "TARGET_SH2A"
+  "@
+	bor.b\\t%1,%0
+	bor.b\\t%1,@(0,%t0)"
+  [(set_attr "length" "4,4")])
+
+;; Take logical or of logical inverse of a specified bit of memory
+;; with the T bit and store its result in the T bit.
+(define_insn "bornot_m2a"
+  [(set (reg:SI T_REG)
+        (ior:SI (reg:SI T_REG)
+                (not:SI (zero_extract:SI
+                    (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
+                    (const_int 1)
+                    (match_operand 1 "const_int_operand" "K03,K03")))))]
+  "TARGET_SH2A"
+  "@
+	bornot.b\\t%1,%0
+	bornot.b\\t%1,@(0,%t0)"
+  [(set_attr "length" "4,4")])
+
+;; Take exclusive or of a specified bit of memory with the T bit and
+;; store its result in the T bit.
+(define_insn "bxor_m2a"
+  [(set (reg:SI T_REG)
+        (xor:SI (reg:SI T_REG)
+                (zero_extract:SI
+                    (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
+                    (const_int 1)
+                    (match_operand 1 "const_int_operand" "K03,K03"))))]
+  "TARGET_SH2A"
+  "@
+	bxor.b\\t%1,%0
+	bxor.b\\t%1,@(0,%t0)"
+  [(set_attr "length" "4,4")])
+
+(define_insn "bit_m2a"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (match_operator:SI 4 "logical_operator"
+          [(zero_extract:SI
+           (mem:QI (match_operand:SI 1 "arith_reg_operand" "r"))
+           (const_int 1)
+           (match_operand 2 "const_int_operand" "K03"))
+        (match_operand:SI 3 "arith_reg_operand" "r")]))]
+  "TARGET_SH2A"
+  "bld\\t#0,%3\;b%f4.b\\t%2,@(0,%1)\;movt\\t%0"
+)
+
+(define_insn "bitnot_m2a"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (match_operator:SI 4 "andor_operator"
+          [(not:SI (zero_extract:SI
+           (mem:QI (match_operand:SI 1 "arith_reg_operand" "r"))
+           (const_int 1)
+           (match_operand 2 "const_int_operand" "K03")))
+        (match_operand:SI 3 "arith_reg_operand" "r")]))]
+  "TARGET_SH2A"
+  "bld\\t#0,%3\;b%e4.b\\t%2,@(0,%1)\;movt\\t%0"
+)
+
 \f
 ;; -------------------------------------------------------------------------
 ;; Peepholes
diff -uprN gcc-4.3-20070921/gcc/testsuite/gcc.target/sh/sh2a-band.c tars/gcc-4.3-20070921/gcc/testsuite/gcc.target/sh/sh2a-band.c
--- gcc-4.3-20070921/gcc/testsuite/gcc.target/sh/sh2a-band.c	1970-01-01 05:30:00.000000000 +0530
+++ tars/gcc-4.3-20070921/gcc/testsuite/gcc.target/sh/sh2a-band.c	2007-10-24 12:28:42.000000000 +0530
@@ -0,0 +1,94 @@
+/* Testcase to check generation of a SH2A specific instruction for
+   "BAND.B #imm3, @(disp12, Rn)" 8-bit  */
+
+/* { dg-do assemble {target sh*-*-*}}  */
+/* { dg-options "-O1" }  */
+/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single
+   -m2a-single-only" }  */
+/* { dg-final { scan-assembler "band.b"} }  */
+
+volatile struct
+{
+  union
+  {
+    unsigned char BYTE;
+    struct
+    {
+      unsigned char BIT7:1;
+      unsigned char BIT6:1;
+      unsigned char BIT5:1;
+      unsigned char BIT4:1;
+      unsigned char BIT3:1;
+      unsigned char BIT2:1;
+      unsigned char BIT1:1;
+      unsigned char BIT0:1;
+    }
+    BIT;
+  }
+  ICR0;
+}
+USRSTR;
+
+volatile union t_IOR
+{
+  unsigned short WORD;
+  struct
+  {
+    unsigned char IOR15:1;
+    unsigned char IOR14:1;
+    unsigned char IOR13:1;
+    unsigned char IOR12:1;
+    unsigned char IOR11:1;
+    unsigned char IOR10:1;
+    unsigned char IOR9:1;
+    unsigned char IOR8:1;
+    unsigned char IOR7:1;
+    unsigned char IOR6:1;
+    unsigned char IOR5:1;
+    unsigned char IOR4:1;
+    unsigned char IOR3:1;
+    unsigned char IOR2:1;
+    unsigned char IOR1:1;
+    unsigned char IOR0:1;
+  }
+  BIT;
+}
+PORT;
+
+int
+main ()
+{
+  volatile unsigned char a;
+
+  /* Instruction generated is BAND.B #imm3, @(disp12, Rn)  */
+  USRSTR.ICR0.BIT.BIT3 = USRSTR.ICR0.BIT.BIT4 & USRSTR.ICR0.BIT.BIT1;
+  USRSTR.ICR0.BIT.BIT2 = USRSTR.ICR0.BIT.BIT6 & USRSTR.ICR0.BIT.BIT6;
+  USRSTR.ICR0.BIT.BIT4 = USRSTR.ICR0.BIT.BIT2 & USRSTR.ICR0.BIT.BIT4;
+  USRSTR.ICR0.BIT.BIT6 = USRSTR.ICR0.BIT.BIT1 & USRSTR.ICR0.BIT.BIT3;
+
+  a = USRSTR.ICR0.BIT.BIT0 & USRSTR.ICR0.BIT.BIT1;
+  a = USRSTR.ICR0.BIT.BIT5 & USRSTR.ICR0.BIT.BIT7;
+  a = USRSTR.ICR0.BIT.BIT2 & USRSTR.ICR0.BIT.BIT6;
+
+  PORT.BIT.IOR13 = PORT.BIT.IOR0  &  USRSTR.ICR0.BIT.BIT7;
+  PORT.BIT.IOR15 = PORT.BIT.IOR6  &  USRSTR.ICR0.BIT.BIT2;
+  PORT.BIT.IOR3  = PORT.BIT.IOR2  &  USRSTR.ICR0.BIT.BIT5;
+  PORT.BIT.IOR1  = PORT.BIT.IOR13 &  USRSTR.ICR0.BIT.BIT1;
+
+  PORT.BIT.IOR1  = PORT.BIT.IOR2  &  USRSTR.ICR0.BIT.BIT1;
+  PORT.BIT.IOR11 = PORT.BIT.IOR9  &  USRSTR.ICR0.BIT.BIT2;
+  PORT.BIT.IOR8  = PORT.BIT.IOR14 &  USRSTR.ICR0.BIT.BIT5;
+
+  PORT.BIT.IOR10 &= USRSTR.ICR0.BIT.BIT1;
+  PORT.BIT.IOR1  &= USRSTR.ICR0.BIT.BIT2;
+  PORT.BIT.IOR5  &= USRSTR.ICR0.BIT.BIT5;
+  PORT.BIT.IOR14 &= USRSTR.ICR0.BIT.BIT4;
+
+  /* Instruction generated on using size optimization option "-Os".  */
+  a = a & USRSTR.ICR0.BIT.BIT1;
+  a = a & USRSTR.ICR0.BIT.BIT4;
+  a = a & USRSTR.ICR0.BIT.BIT0;
+
+  return 0;
+}
+
diff -uprN gcc-4.3-20070921/gcc/testsuite/gcc.target/sh/sh2a-bclrmem.c tars/gcc-4.3-20070921/gcc/testsuite/gcc.target/sh/sh2a-bclrmem.c
--- gcc-4.3-20070921/gcc/testsuite/gcc.target/sh/sh2a-bclrmem.c	1970-01-01 05:30:00.000000000 +0530
+++ tars/gcc-4.3-20070921/gcc/testsuite/gcc.target/sh/sh2a-bclrmem.c	2007-10-24 12:32:21.000000000 +0530
@@ -0,0 +1,58 @@
+/* Testcase to check generation of a SH2A specific instruction
+   "BCLR #imm3,@(disp12,Rn)" 16-bit union  */
+
+/* { dg-do assemble {target sh*-*-*}}  */
+/* { dg-options "-O1" }  */
+/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single
+   -m2a-single-only" }  */
+/* { dg-final { scan-assembler "bclr"} }  */
+/* { dg-final { scan-assembler "bclr.b"} }  */
+
+volatile union un_paddr
+{
+  unsigned short WORD;
+  struct
+  {
+    unsigned char B15:1;
+    unsigned char B14:1;
+    unsigned char B13:1;
+    unsigned char B12:1;
+    unsigned char B11:1;
+    unsigned char B10:1;
+    unsigned char B9:1;
+    unsigned char B8:1;
+    unsigned char B7:1;
+    unsigned char B6:1;
+    unsigned char B5:1;
+    unsigned char B4:1;
+    unsigned char B3:1;
+    unsigned char B2:1;
+    unsigned char B1:1;
+    unsigned char B0:1;
+  }
+  BIT;
+}
+PADDR;
+
+int
+main ()
+{
+  PADDR.BIT.B0 = 0;
+  PADDR.BIT.B3 = 0;
+  PADDR.BIT.B6 = 0;
+
+  PADDR.BIT.B1 &= 0;
+  PADDR.BIT.B4 &= 0;
+  PADDR.BIT.B7 &= 0;
+
+  PADDR.BIT.B10 = 0;
+  PADDR.BIT.B13 = 0;
+  PADDR.BIT.B15 = 0;
+
+  PADDR.BIT.B9 &= 0;
+  PADDR.BIT.B12 &= 0;
+  PADDR.BIT.B14 &= 0;
+
+  return 0;
+}
+
diff -uprN gcc-4.3-20070921/gcc/testsuite/gcc.target/sh/sh2a-bldbst.c tars/gcc-4.3-20070921/gcc/testsuite/gcc.target/sh/sh2a-bldbst.c
--- gcc-4.3-20070921/gcc/testsuite/gcc.target/sh/sh2a-bldbst.c	1970-01-01 05:30:00.000000000 +0530
+++ tars/gcc-4.3-20070921/gcc/testsuite/gcc.target/sh/sh2a-bldbst.c	2007-10-24 12:33:29.000000000 +0530
@@ -0,0 +1,47 @@
+/* Testcase to check generation of a SH2A specific instruction for 8-bit
+   union -
+ *   BLD #imm3, (Rn)
+ *   BLD.B #imm3, @(disp12, Rn)
+ *   BST.B #imm3, @(disp12, Rn)
+*/
+
+/* { dg-do assemble {target sh*-*-*}}  */
+/* { dg-options "-Os" }  */
+/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single
+   -m2a-single-only" }  */
+/* { dg-final { scan-assembler "bld"} }  */
+/* { dg-final { scan-assembler "bld.b"} }  */
+/* { dg-final { scan-assembler "bst.b"} }  */
+
+volatile struct
+{
+  union
+  {
+    unsigned char BYTE;
+    struct
+    {
+      unsigned char BIT7:1;
+      unsigned char BIT6:1;
+      unsigned char BIT5:1;
+      unsigned char BIT4:1;
+      unsigned char BIT3:1;
+      unsigned char BIT2:1;
+      unsigned char BIT1:1;
+      unsigned char BIT0:1;
+    }
+    BIT;
+  }
+  ICR0;
+}
+USRSTR;
+
+int
+main ()
+{
+  volatile unsigned char a, b, c;
+  USRSTR.ICR0.BIT.BIT6 &= a;
+  USRSTR.ICR0.BIT.BIT5 |= b;
+  USRSTR.ICR0.BIT.BIT4 ^= c;
+  return 0;
+}
+
diff -uprN gcc-4.3-20070921/gcc/testsuite/gcc.target/sh/sh2a-bor.c tars/gcc-4.3-20070921/gcc/testsuite/gcc.target/sh/sh2a-bor.c
--- gcc-4.3-20070921/gcc/testsuite/gcc.target/sh/sh2a-bor.c	1970-01-01 05:30:00.000000000 +0530
+++ tars/gcc-4.3-20070921/gcc/testsuite/gcc.target/sh/sh2a-bor.c	2007-10-24 12:29:41.000000000 +0530
@@ -0,0 +1,94 @@
+/* Testcase to check generation of a SH2A specific instruction for
+   "BOR.B #imm3, @(disp12, Rn)" 8-bit  */
+
+/* { dg-do assemble {target sh*-*-*}}  */
+/* { dg-options "-O1" } */
+/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single
+   -m2a-single-only" }  */
+/* { dg-final { scan-assembler "bor.b"} }  */
+
+volatile struct
+{
+  union
+  {
+    unsigned char BYTE;
+    struct
+    {
+      unsigned char BIT7:1;
+      unsigned char BIT6:1;
+      unsigned char BIT5:1;
+      unsigned char BIT4:1;
+      unsigned char BIT3:1;
+      unsigned char BIT2:1;
+      unsigned char BIT1:1;
+      unsigned char BIT0:1;
+    }
+    BIT;
+  }
+  ICR0;
+}
+USRSTR;
+
+volatile union t_IOR
+{
+  unsigned short WORD;
+  struct
+  {
+    unsigned char IOR15:1;
+    unsigned char IOR14:1;
+    unsigned char IOR13:1;
+    unsigned char IOR12:1;
+    unsigned char IOR11:1;
+    unsigned char IOR10:1;
+    unsigned char IOR9:1;
+    unsigned char IOR8:1;
+    unsigned char IOR7:1;
+    unsigned char IOR6:1;
+    unsigned char IOR5:1;
+    unsigned char IOR4:1;
+    unsigned char IOR3:1;
+    unsigned char IOR2:1;
+    unsigned char IOR1:1;
+    unsigned char IOR0:1;
+  }
+  BIT;
+}
+PORT;
+
+int
+main ()
+{
+  volatile unsigned char a;
+
+  /* Instruction generated is BOR.B #imm3, @(disp12, Rn)  */
+  USRSTR.ICR0.BIT.BIT3 = USRSTR.ICR0.BIT.BIT4 | USRSTR.ICR0.BIT.BIT1;
+  USRSTR.ICR0.BIT.BIT2 = USRSTR.ICR0.BIT.BIT6 | USRSTR.ICR0.BIT.BIT6;
+  USRSTR.ICR0.BIT.BIT4 = USRSTR.ICR0.BIT.BIT2 | USRSTR.ICR0.BIT.BIT4;
+  USRSTR.ICR0.BIT.BIT6 = USRSTR.ICR0.BIT.BIT1 | USRSTR.ICR0.BIT.BIT3;
+
+  a = USRSTR.ICR0.BIT.BIT0 | USRSTR.ICR0.BIT.BIT1;
+  a = USRSTR.ICR0.BIT.BIT5 | USRSTR.ICR0.BIT.BIT7;
+  a = USRSTR.ICR0.BIT.BIT2 | USRSTR.ICR0.BIT.BIT6;
+
+  PORT.BIT.IOR13 = PORT.BIT.IOR0  |  USRSTR.ICR0.BIT.BIT7;
+  PORT.BIT.IOR15 = PORT.BIT.IOR6  |  USRSTR.ICR0.BIT.BIT2;
+  PORT.BIT.IOR3  = PORT.BIT.IOR2  |  USRSTR.ICR0.BIT.BIT5;
+  PORT.BIT.IOR1  = PORT.BIT.IOR13 |  USRSTR.ICR0.BIT.BIT1;
+
+  PORT.BIT.IOR1  = PORT.BIT.IOR2  |  USRSTR.ICR0.BIT.BIT1;
+  PORT.BIT.IOR11 = PORT.BIT.IOR9  |  USRSTR.ICR0.BIT.BIT2;
+  PORT.BIT.IOR8  = PORT.BIT.IOR14 |  USRSTR.ICR0.BIT.BIT5;
+
+  PORT.BIT.IOR10 |= USRSTR.ICR0.BIT.BIT1;
+  PORT.BIT.IOR1  |= USRSTR.ICR0.BIT.BIT2;
+  PORT.BIT.IOR5  |= USRSTR.ICR0.BIT.BIT5;
+  PORT.BIT.IOR14 |= USRSTR.ICR0.BIT.BIT4;
+
+  /* Instruction generated on using size optimization option "-Os".  */
+  a = a & USRSTR.ICR0.BIT.BIT1;
+  a = a & USRSTR.ICR0.BIT.BIT4;
+  a = a & USRSTR.ICR0.BIT.BIT0;
+
+  return 0;
+}
+
diff -uprN gcc-4.3-20070921/gcc/testsuite/gcc.target/sh/sh2a-bsetmem.c tars/gcc-4.3-20070921/gcc/testsuite/gcc.target/sh/sh2a-bsetmem.c
--- gcc-4.3-20070921/gcc/testsuite/gcc.target/sh/sh2a-bsetmem.c	1970-01-01 05:30:00.000000000 +0530
+++ tars/gcc-4.3-20070921/gcc/testsuite/gcc.target/sh/sh2a-bsetmem.c	2007-10-24 12:31:37.000000000 +0530
@@ -0,0 +1,58 @@
+/* Testcase to check generation of a SH2A specific instruction
+   "BSET #imm3,@(disp12,Rn)" 16-bit union  */
+
+/* { dg-do assemble {target sh*-*-*}}  */
+/* { dg-options "-O1" }  */
+/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single
+   -m2a-single-only" }  */
+/* { dg-final { scan-assembler "bclr"} }  */
+/* { dg-final { scan-assembler "bclr.b"} }  */
+
+volatile union un_paddr
+{
+  unsigned short WORD;
+  struct
+  {
+    unsigned char B15:1;
+    unsigned char B14:1;
+    unsigned char B13:1;
+    unsigned char B12:1;
+    unsigned char B11:1;
+    unsigned char B10:1;
+    unsigned char B9:1;
+    unsigned char B8:1;
+    unsigned char B7:1;
+    unsigned char B6:1;
+    unsigned char B5:1;
+    unsigned char B4:1;
+    unsigned char B3:1;
+    unsigned char B2:1;
+    unsigned char B1:1;
+    unsigned char B0:1;
+  }
+  BIT;
+}
+PADDR;
+
+int
+main ()
+{
+  PADDR.BIT.B0 = 1;
+  PADDR.BIT.B3 = 1;
+  PADDR.BIT.B6 = 1;
+
+  PADDR.BIT.B1 |= 1;
+  PADDR.BIT.B4 |= 1;
+  PADDR.BIT.B7 |= 1;
+
+  PADDR.BIT.B10 = 1;
+  PADDR.BIT.B13 = 1;
+  PADDR.BIT.B15 = 1;
+
+  PADDR.BIT.B9  |= 1;
+  PADDR.BIT.B12 |= 1;
+  PADDR.BIT.B14 |= 1;
+
+  return 0;
+}
+
diff -uprN gcc-4.3-20070921/gcc/testsuite/gcc.target/sh/sh2a-bxor.c tars/gcc-4.3-20070921/gcc/testsuite/gcc.target/sh/sh2a-bxor.c
--- gcc-4.3-20070921/gcc/testsuite/gcc.target/sh/sh2a-bxor.c	1970-01-01 05:30:00.000000000 +0530
+++ tars/gcc-4.3-20070921/gcc/testsuite/gcc.target/sh/sh2a-bxor.c	2007-10-24 12:30:39.000000000 +0530
@@ -0,0 +1,94 @@
+/* Testcase to check generation of a SH2A specific instruction for
+   "BXOR.B #imm3, @(disp12, Rn)" 8-bit  */
+
+/* { dg-do assemble {target sh*-*-*}}  */
+/* { dg-options "-O1" }  */
+/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single
+   -m2a-single-only" }  */
+/* { dg-final { scan-assembler "bxor.b"} }  */
+
+volatile struct
+{
+  union
+  {
+    unsigned char BYTE;
+    struct
+    {
+      unsigned char BIT7:1;
+      unsigned char BIT6:1;
+      unsigned char BIT5:1;
+      unsigned char BIT4:1;
+      unsigned char BIT3:1;
+      unsigned char BIT2:1;
+      unsigned char BIT1:1;
+      unsigned char BIT0:1;
+    }
+    BIT;
+  }
+  ICR0;
+}
+USRSTR;
+
+volatile union t_IOR
+{
+  unsigned short WORD;
+  struct
+  {
+    unsigned char IOR15:1;
+    unsigned char IOR14:1;
+    unsigned char IOR13:1;
+    unsigned char IOR12:1;
+    unsigned char IOR11:1;
+    unsigned char IOR10:1;
+    unsigned char IOR9:1;
+    unsigned char IOR8:1;
+    unsigned char IOR7:1;
+    unsigned char IOR6:1;
+    unsigned char IOR5:1;
+    unsigned char IOR4:1;
+    unsigned char IOR3:1;
+    unsigned char IOR2:1;
+    unsigned char IOR1:1;
+    unsigned char IOR0:1;
+  }
+  BIT;
+}
+PORT;
+
+int
+main ()
+{
+  volatile unsigned char a;
+
+  /* Instruction generated is BXOR.B #imm3, @(disp12, Rn)  */
+  USRSTR.ICR0.BIT.BIT3 = USRSTR.ICR0.BIT.BIT4 ^ USRSTR.ICR0.BIT.BIT1;
+  USRSTR.ICR0.BIT.BIT2 = USRSTR.ICR0.BIT.BIT6 ^ USRSTR.ICR0.BIT.BIT6;
+  USRSTR.ICR0.BIT.BIT4 = USRSTR.ICR0.BIT.BIT2 ^ USRSTR.ICR0.BIT.BIT4;
+  USRSTR.ICR0.BIT.BIT6 = USRSTR.ICR0.BIT.BIT1 ^ USRSTR.ICR0.BIT.BIT3;
+
+  a = USRSTR.ICR0.BIT.BIT0 ^ USRSTR.ICR0.BIT.BIT1;
+  a = USRSTR.ICR0.BIT.BIT5 ^ USRSTR.ICR0.BIT.BIT7;
+  a = USRSTR.ICR0.BIT.BIT2 ^ USRSTR.ICR0.BIT.BIT6;
+
+  PORT.BIT.IOR13 = PORT.BIT.IOR0  ^  USRSTR.ICR0.BIT.BIT7;
+  PORT.BIT.IOR15 = PORT.BIT.IOR6  ^  USRSTR.ICR0.BIT.BIT2;
+  PORT.BIT.IOR3  = PORT.BIT.IOR2  ^  USRSTR.ICR0.BIT.BIT5;
+  PORT.BIT.IOR1  = PORT.BIT.IOR13 ^  USRSTR.ICR0.BIT.BIT1;
+
+  PORT.BIT.IOR1  = PORT.BIT.IOR2  ^  USRSTR.ICR0.BIT.BIT1;
+  PORT.BIT.IOR11 = PORT.BIT.IOR9  ^  USRSTR.ICR0.BIT.BIT2;
+  PORT.BIT.IOR8  = PORT.BIT.IOR14 ^  USRSTR.ICR0.BIT.BIT5;
+
+  PORT.BIT.IOR10 ^= USRSTR.ICR0.BIT.BIT1;
+  PORT.BIT.IOR1  ^= USRSTR.ICR0.BIT.BIT2;
+  PORT.BIT.IOR5  ^= USRSTR.ICR0.BIT.BIT5;
+  PORT.BIT.IOR14 ^= USRSTR.ICR0.BIT.BIT4;
+
+  /* Instruction generated on using size optimization option "-Os".  */
+  a = a ^ USRSTR.ICR0.BIT.BIT1;
+  a = a ^ USRSTR.ICR0.BIT.BIT4;
+  a = a ^ USRSTR.ICR0.BIT.BIT0;
+
+  return 0;
+}
+

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH,SH] Add SH2A new instructions 6/6
  2007-10-25 13:53 [PATCH,SH] Add SH2A new instructions 6/6 Naveen H.S.
@ 2007-10-28 10:46 ` Kaz Kojima
  2008-04-02 12:10   ` Naveen H.S.
  0 siblings, 1 reply; 14+ messages in thread
From: Kaz Kojima @ 2007-10-28 10:46 UTC (permalink / raw)
  To: naveen.hs; +Cc: gcc-patches, Anil.Paranjape, Prafulla.Thakare

"Naveen H.S." <naveen.hs@kpitcummins.com> wrote:
> The implemented bit instructions resulted in very good optimization
> of the bit operations.

Could you show us some numbers how this results in good
optimizations?

> However, the bit instructions are not getting
> generated more frequently after the above mentioned patch. Please
> suggest the modifications to be done on the present patch to generate
> bit instructions as earlier.

I have no idea.  In general, if you don't get the expected
instruction, the rtl and tree debug dumps would be your friends.

I'm concerned with that the use of bitwise memory instructions
impacts on the performance and the code size.
I guess that it will make many 8-bit memory accesses for
operations on bit fields which are currently done on 32-bit
registers at a time.
Although those bitwise memory insns would be better for
the volatile access of a bit in memory like as your testcases
added for new insns or other rather special cases, it might
be worse on the average working set of programs.

Please consider the comment in the previous mail:
> You should confirm that the use of SH2A bitwise operations doesn't
> cause performance/size regressions with real applications.  If it's
> hard to prove, the use of bitwise operations should be controlled
> with the option -mbitops or some such which is off by default.

Here are some comments on each parts of the patch.

There are no tests for "b*not" instructions.  We should avoid
adding things which we can't test at all.  If they are hard
to use in the current compiler, drop the related hunks from
the patch:

> --- gcc-4.3-20070921/gcc/config/sh/predicates.md	2007-08-02 16:19:31.000000000 +0530
> +++ tars/gcc-4.3-20070921/gcc/config/sh/predicates.md	2007-10-24 12:51:53.000000000 +0530
> @@ -516,6 +516,11 @@
>  (define_predicate "logical_operator"
>    (match_code "and,ior,xor"))
>  
> +;; Recognize valid operators for bitnot instructions.
> +
> +(define_predicate "andor_operator"
> +  (match_code "and,ior"))
> +
>  ;; Like arith_reg_operand, but for register source operands of narrow
>  ;; logical SHMEDIA operations: forbid subregs of DImode / TImode regs.

and bldnot_m2a, bandnot_m2a, bornot_m2a, bitnot_m2a insns.

bld_genreg, *bld_genregqi, bit_m2a and bitnot_m2a generate
multiple instructions as text and also have no length attribute.
These parts are not Ok and should be dropped from the patch.

> --- gcc-4.3-20070921/gcc/config/sh/sh.c	2007-10-24 12:21:48.000000000 +0530
> +++ tars/gcc-4.3-20070921/gcc/config/sh/sh.c	2007-10-24 12:26:33.000000000 +0530
> @@ -678,6 +678,9 @@ print_operand_address (FILE *stream, rtx
>     'U'  Likewise for {LD,ST}{HI,LO}.
>     'V'  print the position of a single bit set.
>     'W'  print the position of a single bit cleared.
> +   'f'  output the bit operator.
> +   'e'  output the bitnot operator.
[snip]
> +
> +    case 'f':
> +      switch (GET_CODE (x))
> +        {
> +        case IOR:
> +          fprintf (stream, "or");
> +          break;
> +        case XOR:
> +          fprintf (stream, "xor");
> +          break;
> +        case AND:
> +          fprintf (stream, "and");
> +          break;
> +        default:
> +          break;
> +        }
> +      break;
> +
> +    case 'e':
> +      switch (GET_CODE (x))
> +        {
> +        case IOR:
> +          fprintf (stream, "ornot");
> +          break;
> +        case AND:
> +          fprintf (stream, "andnot");
> +          break;
> +        default:
> +          break;
> +        }
> +      break;

We should avoid adding new operand formats if possible.  Even
when we add all b*not insns in the future, we can use the explicit
names in the asm text.

> --- gcc-4.3-20070921/gcc/testsuite/gcc.target/sh/sh2a-band.c	1970-01-01 05:30:00.000000000 +0530
> +++ tars/gcc-4.3-20070921/gcc/testsuite/gcc.target/sh/sh2a-band.c	2007-10-24 12:28:42.000000000 +0530
> @@ -0,0 +1,94 @@
> +/* Testcase to check generation of a SH2A specific instruction for
> +   "BAND.B #imm3, @(disp12, Rn)" 8-bit  */

The last "8-bit" is pointless.
An English sentence needs a period at the end.  Other new tests
have the same issue.

> +/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single
> +   -m2a-single-only" }  */

I thought that a dg- directive in testcase should be a single line,
though I'm wrong about it.  It'd be safer to make it to a one long
line.

> --- gcc-4.3-20070921/gcc/testsuite/gcc.target/sh/sh2a-bldbst.c	1970-01-01 05:30:00.000000000 +0530
> +++ tars/gcc-4.3-20070921/gcc/testsuite/gcc.target/sh/sh2a-bldbst.c	2007-10-24 12:33:29.000000000 +0530
> @@ -0,0 +1,47 @@
> +/* Testcase to check generation of a SH2A specific instruction for 8-bit
> +   union -
> + *   BLD #imm3, (Rn)
> + *   BLD.B #imm3, @(disp12, Rn)
> + *   BST.B #imm3, @(disp12, Rn)
> +*/

"instruction for 8-bit union" is bogus.  Maybe

/* A testcase to check generation of the following SH2A specific
   instructions.

    BLD #imm3, Rn
    BLD.B #imm3, @(disp12, Rn)
    BST.B #imm3, @(disp12, Rn)
 */

Please use correct formats of ChangeLog entry.  See existing
ChangeLog entries as your guide.  New testcases need new entries
in gcc/testsuite/ChangeLog.
Some examples about format issues here.  I've given alternatives
in a few cases to clarify the format problems.

> 2007-10-25	Naveen.H.S naveen.hs@kpitcummins.com

  200z-xx-yy  Naveen.H.S  <naveen.hs@kpitcummins.com>
            ^^ 2 spaces ^^^ 2 spaces and use <email-address>

> 	* config/sh/constraints.md: K03, K12, Sbw : New constraints.

	* config/sh/constraints.md (K03, K12, Sbw): New constraints.

> 	* config/sh/predicates.md (bitwise_memory_operand) : New
> predicate.

Indentation or a long line.  Remove a space after ).

> 	* config/sh/sh.c (print_operand): "f" bit operator
> 	"e" bitnot operator.
> 	"t" prints memory address of a register.

Use English sentences.  Perhaps simply

 	* config/sh/sh.c (print_operand): Add %t operand code.

> 	* config/sh/sh.h (sh_args): Add condition for SH2A.

Perhaps

	* config/sh/sh.h (GO_IF_LEGITIMATE_INDEX): Add condition
	for SH2A.
?

> 	* config/sh/sh.md (extendqisi2_compact): enable 4-byte mov.b 
> 	instructions.
> 	(extendqihi2): enable 4-byte mov.b instructions.
> 	(movqi_i): enable 4-byte mov.b instructions.

English sentences in ChangeLog should start with a capital.

	* config/sh/sh.md (extendqisi2_compact): Add the alternative
	for SH2A 4-byte mov.b.
	(extendqihi2): Likewise.
	(movqi_i): Likewise.

> 	(insv): Add conditions to generate BSET, BCLR and BST
> instructions in 
> 	memory mode.
> 	(extv): Add conditions to generate BLD instruction in memory
> mode.
> 	(extzv): Add conditions to generate BLD instruction in memory
> mode.

Long lines?  It looks that capitalized opcodes are not appropriate here.

	(insv): Use bset, bclr and bst instructions for SH2A if possible.
	(extv): Use bld instruction for SH2A if possible.
	(extzv): Likewise.

> 	bclr_m2a, bset_m2a, bst_m2a, bld_m2a, bld_reg, *bld_regqi,
> bld_reg1, 
> 	bld_regqi1, bldnot_m2a, band_m2a, bandnot_m2a, bor_m2a,

Parentheses needed.  It looks that there are no bld_reg1 and
bld_regqi1 in your patch.

	(bclr_m2a, bset_m2a, bst_m2a, bld_m2a, bld_reg, *bld_regqi,
	band_m2a, bor_m2a, bxor_m2a): New insns.

Regards,
	kaz

^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [PATCH,SH] Add SH2A new instructions 6/6
  2007-10-28 10:46 ` Kaz Kojima
@ 2008-04-02 12:10   ` Naveen H.S.
  2008-04-02 13:46     ` Kaz Kojima
  0 siblings, 1 reply; 14+ messages in thread
From: Naveen H.S. @ 2008-04-02 12:10 UTC (permalink / raw)
  To: Kaz Kojima; +Cc: gcc-patches, Prafulla Thakare

[-- Attachment #1: Type: text/plain, Size: 2414 bytes --]

Hi Kaz,

Please find the revised patch attached "sh2a6.patch" as per the
suggestions. Thanks a lot for the valuable guidance.

>> the use of bitwise operations should be controlled with the option
>> -mbitops

Done. Some hunks of the patch are removed as per the suggestion.

>> bit_m2a and bitnot_m2a generate multiple instructions as text and 
>> also have no length attribute.

These patterns generate optimized code for performing logical operations
on bits in memory. Length attributes are added for these instructions.

The patch is tested using the C and C++ testsuite for all the SH2A
combinations.

ChangeLog
2008-04-02  Naveen.H.S  <naveen.hs@kpitcummins.com>
	
	* doc/invoke.texi: Document -mbitops for SH.

	* config/sh/constraints.md (K03, K12, Sbv, Sbw): New 
	constraints.
	* config/sh/predicates.md (bitwise_memory_operand): New
	predicate.
	* config/sh/sh.c (print_operand): Add %t operand code.
	* config/sh/sh.h (GO_IF_LEGITIMATE_INDEX): Add condition
	for SH2A.
	* config/sh/sh.md (*iorsi3_bset): Move the instruction above
	iorsi3_compact.
	(extendqisi2_compact): Add the alternative for SH2A 4-byte
	mov.b.
	(extendqihi2): Likewise.
	(movqi_i): Likewise.
	(insv): Use bset, bclr and bst instructions for SH2A if
	possible.
	(extv): Use bld instruction for SH2A if possible.
	(extzv): Likewise.
	(bclr_m2a, bclrmem_m2a, bset_m2a, bsetmem_m2a, bst_m2a, bld_m2a,
	bldsign_m2a, bld_reg, *bld_regqi, band_m2a, bandreg_m2a,
bor_m2a, 
	borreg_m2a, bxor_m2a, bxorreg_m2a): New insns.
	(bset.b, bclr.b): Define peepholes.
	* config/sh/sh.opt: New option bitops is added to generate bit
	instructions.  
	
	* gcc.target/sh/sh2a-band.c: New test.
	* gcc.target/sh/sh2a-bclrmem.c: New test.
	* gcc.target/sh/sh2a-bld.c: New test.
	* gcc.target/sh/sh2a-bor.c: New test.
	* gcc.target/sh/sh2a-bsetmem.c: New test.
	* gcc.target/sh/sh2a-bxor.c: New test.

Regards,
Naveen.H.S.
KPIT Cummins Infosystems Ltd,
Pune (INDIA) 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~	
Free download of GNU based tool-chains for Renesas' SH, H8, R8C, M16C	
and M32C Series. The following site also offers free technical support	
to its users. Visit http://www.kpitgnutools.com for details. 	
Latest versions of KPIT GNU tools were released on February 4, 2008.	
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~	

[-- Attachment #2: sh2a6.patch --]
[-- Type: application/octet-stream, Size: 30779 bytes --]

--- /gcc/doc/invoke.texi	2008-03-28 23:47:00.000000000 +0530
+++ /gcc/doc/invoke.texi	2008-04-02 10:06:13.000000000 +0530
@@ -744,7 +744,7 @@ See RS/6000 and PowerPC Options.
 -m5-compact  -m5-compact-nofpu @gol
 -mb  -ml  -mdalign  -mrelax @gol
 -mbigtable  -mfmovd  -mhitachi -mrenesas -mno-renesas -mnomacsave @gol
--mieee  -misize  -minline-ic_invalidate -mpadstruct  -mspace @gol
+-mieee  -mbitops  -misize  -minline-ic_invalidate -mpadstruct  -mspace @gol
 -mprefergot  -musermode -multcost=@var{number} -mdiv=@var{strategy} @gol
 -mdivsi3_libfunc=@var{name}  @gol
 -madjust-unroll -mindexed-addressing -mgettrcost=@var{number} -mpt-fixed @gol
@@ -13885,6 +13885,10 @@ linker option @option{-relax}.
 Use 32-bit offsets in @code{switch} tables.  The default is to use
 16-bit offsets.
 
+@item -mbitops
+@opindex mbitops
+Enable the use of bit instructions.
+
 @item -mfmovd
 @opindex mfmovd
 Enable the use of the instruction @code{fmovd}.
--- /gcc/config/sh/constraints.md	2008-03-25 19:14:00.000000000 +0530
+++ /gcc/config/sh/constraints.md	2008-04-02 10:10:22.000000000 +0530
@@ -125,11 +125,21 @@
   (and (match_code "const_int")
        (match_test "CONST_OK_FOR_J16 (ival)")))
 
+(define_constraint "K03"
+  "An unsigned 3-bit constant, as used in SH2A bclr, bset, etc."
+  (and (match_code "const_int")
+       (match_test "ival >= 0 && ival <= 7")))
+
 (define_constraint "K08"
   "An unsigned 8-bit constant, as used in and, or, etc."
   (and (match_code "const_int")
        (match_test "ival >= 0 && ival <= 255")))
  
+(define_constraint "K12"
+  "An unsigned 8-bit constant, as used in SH2A 12-bit display."
+  (and (match_code "const_int")
+       (match_test "ival >= 0 && ival <= 4095")))
+
 (define_constraint "K16"
   "An unsigned 16-bit constant, as used in SHmedia shori."
   (and (match_code "const_int")
@@ -239,3 +249,15 @@
   "@internal"
   (and (match_test "memory_operand (op, GET_MODE (op))")
        (match_test "GET_CODE (XEXP (op, 0)) != PLUS")))
+
+(define_memory_constraint "Sbv"
+  "A memory reference, as used in SH2A bclr.b, bset.b, etc."
+  (and (match_test "MEM_P (op) && GET_MODE (op) == QImode")
+       (match_test "REG_P (XEXP (op, 0))")))
+
+(define_memory_constraint "Sbw"
+  "A memory reference, as used in SH2A bclr.b, bset.b, etc."
+  (and (match_test "MEM_P (op) && GET_MODE (op) == QImode")
+       (match_test "GET_CODE (XEXP (op, 0)) == PLUS")
+       (match_test "REG_P (XEXP (XEXP (op, 0), 0))")
+       (match_test "satisfies_constraint_K12 (XEXP (XEXP (op, 0), 1))")))
--- /gcc/config/sh/predicates.md	2007-08-02 16:19:31.000000000 +0530
+++ /gcc/config/sh/predicates.md	2008-04-02 10:06:13.000000000 +0530
@@ -789,3 +789,19 @@
     return 0;
   return arith_reg_operand (op, mode);
 })
+
+(define_predicate "bitwise_memory_operand"
+  (match_code "mem")
+{
+  if (GET_CODE (op) == MEM)
+    {
+      if (REG_P (XEXP (op, 0)))
+	return 1;
+
+      if (GET_CODE (XEXP (op, 0)) == PLUS
+	  && GET_CODE (XEXP (XEXP (op, 0), 0)) == REG
+	  && satisfies_constraint_K12 (XEXP (XEXP (op, 0), 1)))
+        return 1;
+    }
+  return 0;
+})
--- /gcc/config/sh/sh.c	2008-03-25 19:14:00.000000000 +0530
+++ /gcc/config/sh/sh.c	2008-04-02 10:11:19.000000000 +0530
@@ -683,6 +683,7 @@ print_operand_address (FILE *stream, rtx
    'U'  Likewise for {LD,ST}{HI,LO}.
    'V'  print the position of a single bit set.
    'W'  print the position of a single bit cleared.
+   't'  print a memory address which is a register.
    'u'  prints the lowest 16 bits of CONST_INT, as an unsigned value.
    'o'  output an operator.  */
 
@@ -822,6 +823,21 @@ print_operand (FILE *stream, rtx x, int 
 	  break;
 	}
       break;
+
+    case 't':
+      gcc_assert (GET_CODE (x) == MEM);
+      x = XEXP (x, 0);
+      switch (GET_CODE (x))
+	{
+	case REG:
+	case SUBREG:
+	  print_operand (stream, x, 0);
+	  break;
+	default:
+	  break;
+	}
+      break;
+
     case 'o':
       switch (GET_CODE (x))
 	{
--- /gcc/config/sh/sh.h	2008-02-29 18:16:19.000000000 +0530
+++ /gcc/config/sh/sh.h	2008-04-02 10:06:13.000000000 +0530
@@ -2449,6 +2449,12 @@ struct sh_args {
 	    else							\
 	      break;							\
 	  }								\
+	if (TARGET_SH2A)						\
+	  {								\
+	    if (GET_MODE_SIZE (MODE) == 1				\
+		&& (unsigned) INTVAL (OP) < 4096)			\
+	    goto LABEL;							\
+	  }								\
 	if (MODE_DISP_OK_4 ((OP), (MODE)))  goto LABEL;		      	\
 	if (MODE_DISP_OK_8 ((OP), (MODE)))  goto LABEL;		      	\
       }									\
--- /gcc/config/sh/sh.md	2008-03-25 19:14:00.000000000 +0530
+++ /gcc/config/sh/sh.md	2008-04-02 11:35:39.000000000 +0530
@@ -3242,6 +3242,14 @@ label:
   ""
   "")
 
+(define_insn "*iorsi3_bset"
+  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
+        (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0")
+        	(match_operand:SI 2 "const_int_operand" "Pso")))]
+  "TARGET_SH2A && satisfies_constraint_Pso (operands[2])"
+  "bset\\t%V2,%0"
+  [(set_attr "type" "arith")])
+
 (define_insn "*iorsi3_compact"
   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
 	(ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
@@ -3260,14 +3268,6 @@ label:
 	ori	%1, %2, %0"
   [(set_attr "type" "arith_media")])
 
-(define_insn "*iorsi3_bset"
-  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
-	(ior:SI (match_operand:SI 1 "arith_reg_operand" "%0")
-	(match_operand:SI 2 "const_int_operand" "Pso")))]
-  "TARGET_SH2A && satisfies_constraint_Pso (operands[2])"
-  "bset\\t%V2,%0"
-  [(set_attr "type" "arith")])
-
 (define_insn "iordi3"
   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
 	(ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
@@ -4723,7 +4723,12 @@ label:
   "@
 	exts.b	%1,%0
 	mov.b	%1,%0"
-  [(set_attr "type" "arith,load")])
+  [(set_attr "type" "arith,load")
+   (set_attr_alternative "length"
+     [(const_int 2)
+       (if_then_else
+	(ne (symbol_ref "TARGET_SH2A") (const_int 0))
+	(const_int 4) (const_int 2))])])
 
 (define_insn "*extendqisi2_media"
   [(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -4761,7 +4766,12 @@ label:
   "@
 	exts.b	%1,%0
 	mov.b	%1,%0"
-  [(set_attr "type" "arith,load")])
+  [(set_attr "type" "arith,load")
+   (set_attr_alternative "length"
+     [(const_int 2)
+       (if_then_else
+	(ne (symbol_ref "TARGET_SH2A") (const_int 0))
+	(const_int 4) (const_int 2))])])
 
 /* It would seem useful to combine the truncXi patterns into the movXi
    patterns, but unary operators are ignored when matching constraints,
@@ -5309,7 +5319,19 @@ label:
 	movt	%0
 	sts	%1,%0
 	lds	%1,%0"
- [(set_attr "type" "move,movi8,load,store,arith,prget,prset")])
+ [(set_attr "type" "move,movi8,load,store,arith,prget,prset")
+  (set_attr_alternative "length"
+     [(const_int 2)
+      (const_int 2)
+      (if_then_else
+	(ne (symbol_ref "TARGET_SH2A") (const_int 0))
+	(const_int 4) (const_int 2))
+      (if_then_else
+	(ne (symbol_ref "TARGET_SH2A") (const_int 0))
+	(const_int 4) (const_int 2))
+      (const_int 2)
+      (const_int 2)
+      (const_int 2)])])
 
 (define_insn "*movqi_media"
   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
@@ -11655,6 +11677,36 @@ mov.l\\t1f,r0\\n\\
   HOST_WIDE_INT bitsize, size, v = 0;
   rtx x = operands[3];
 
+  if (TARGET_SH2A && TARGET_BITOPS
+      && (satisfies_constraint_Sbw (operands[0])
+	  || satisfies_constraint_Sbv (operands[0]))
+      && satisfies_constraint_M (operands[1])
+      && satisfies_constraint_K03 (operands[2]))
+    {
+      if (satisfies_constraint_N (operands[3]))
+	{
+	  emit_insn (gen_bclr_m2a (operands[0], operands[2]));
+	  DONE;
+	}
+      else if (satisfies_constraint_M (operands[3]))
+	{
+	  emit_insn (gen_bset_m2a (operands[0], operands[2]));
+	  DONE;
+	}
+      else if ((REG_P (operands[3]) && REGNO (operands[3]) == T_REG)
+		&& satisfies_constraint_M (operands[1]))
+	{
+	  emit_insn (gen_bst_m2a (operands[0], operands[2]));
+	  DONE;
+	}
+      else if (REG_P (operands[3])
+	       && satisfies_constraint_M (operands[1]))
+	{
+	  emit_insn (gen_bld_reg (operands[3], const0_rtx));
+	  emit_insn (gen_bst_m2a (operands[0], operands[2]));
+	  DONE;
+	}
+    }
   /* ??? expmed doesn't care for non-register predicates.  */
   if (! memory_operand (operands[0], VOIDmode)
       || ! immediate_operand (operands[1], VOIDmode)
@@ -11732,8 +11784,19 @@ mov.l\\t1f,r0\\n\\
 	(sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
 			 (match_operand 2 "const_int_operand" "")
 			 (match_operand 3 "const_int_operand" "")))]
-  "TARGET_SH4A_ARCH"
+  "TARGET_SH4A_ARCH || TARGET_SH2A"
 {
+  if (TARGET_SH2A && TARGET_BITOPS
+      && (satisfies_constraint_Sbw (operands[1])
+	  || satisfies_constraint_Sbv (operands[1]))
+      && satisfies_constraint_M (operands[2])
+      && satisfies_constraint_K03 (operands[3]))
+   {
+      emit_insn (gen_bldsign_m2a (operands[1], operands[3]));
+      if (REGNO (operands[0]) != T_REG)
+	emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
+      DONE;
+   }
   if (TARGET_SH4A_ARCH
       && INTVAL (operands[2]) == 32
       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
@@ -11753,8 +11816,19 @@ mov.l\\t1f,r0\\n\\
 	(zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
 			 (match_operand 2 "const_int_operand" "")
 			 (match_operand 3 "const_int_operand" "")))]
-  "TARGET_SH4A_ARCH"
+  "TARGET_SH4A_ARCH || TARGET_SH2A"
 {
+  if (TARGET_SH2A && TARGET_BITOPS
+      && (satisfies_constraint_Sbw (operands[1])
+	  || satisfies_constraint_Sbv (operands[1]))
+      && satisfies_constraint_M (operands[2])
+      && satisfies_constraint_K03 (operands[3]))
+    {
+      emit_insn (gen_bld_m2a (operands[1], operands[3]));
+      if (REGNO (operands[0]) != T_REG)
+	emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
+      DONE;
+    }
   if (TARGET_SH4A_ARCH
       && INTVAL (operands[2]) == 32
       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
@@ -11769,10 +11843,229 @@ mov.l\\t1f,r0\\n\\
   FAIL;
 })
 
+;; SH2A instructions for bitwise operations.
+
+;; Clear a bit in a memory location.
+(define_insn "bclr_m2a"
+  [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
+	(and:QI
+	    (not:QI (ashift:QI (const_int 1)
+			(match_operand:QI 1 "const_int_operand" "K03,K03")))
+	    (match_dup 0)))]
+  "TARGET_SH2A && TARGET_BITOPS"
+  "@
+	bclr.b\\t%1,%0
+	bclr.b\\t%1,@(0,%t0)"
+[(set_attr "length" "4,4")])
+
+(define_insn "bclrmem_m2a"
+  [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
+        (and:QI (match_dup 0)
+                (match_operand:QI 1 "const_int_operand" "Psz,Psz")))]
+  "TARGET_SH2A && satisfies_constraint_Psz (operands[1]) && TARGET_BITOPS"
+  "@
+        bclr.b\\t%W1,%0
+        bclr.b\\t%W1,@(0,%t0)"
+  [(set_attr "length" "4,4")])
+
+;; Set a bit in a memory location.
+(define_insn "bset_m2a"
+  [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
+	(ior:QI
+	    (ashift:QI (const_int 1)
+		       (match_operand:QI 1 "const_int_operand" "K03,K03"))
+	    (match_dup 0)))]
+  "TARGET_SH2A && TARGET_BITOPS"
+  "@
+	bset.b\\t%1,%0
+	bset.b\\t%1,@(0,%t0)"
+  [(set_attr "length" "4,4")])
+
+(define_insn "bsetmem_m2a"
+  [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
+	(ior:QI (match_dup 0)
+		(match_operand:QI 1 "const_int_operand" "Pso,Pso")))]
+  "TARGET_SH2A && satisfies_constraint_Pso (operands[1]) && TARGET_BITOPS"
+  "@
+        bset.b\\t%V1,%0
+        bset.b\\t%V1,@(0,%t0)"
+  [(set_attr "length" "4,4")])
+
+;;; Transfer the contents of the T bit to a specified bit of memory.
+(define_insn "bst_m2a"
+  [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,m")
+	(if_then_else (eq (reg:SI T_REG) (const_int 0))
+	    (and:QI
+		(not:QI (ashift:QI (const_int 1)
+			(match_operand:QI 1 "const_int_operand" "K03,K03")))
+		(match_dup 0))
+	    (ior:QI
+		(ashift:QI (const_int 1) (match_dup 1))
+		(match_dup 0))))]
+  "TARGET_SH2A && TARGET_BITOPS"
+  "@
+	bst.b\\t%1,%0
+	bst.b\\t%1,@(0,%t0)"
+  [(set_attr "length" "4")])
+
+;; Store a specified bit of memory in the T bit.
+(define_insn "bld_m2a"
+  [(set (reg:SI T_REG)
+	(zero_extract:SI
+	    (match_operand:QI 0 "bitwise_memory_operand" "Sbw,Sbv")
+	    (const_int 1)
+	    (match_operand 1 "const_int_operand" "K03,K03")))]
+  "TARGET_SH2A && TARGET_BITOPS"
+  "@
+	bld.b\\t%1,%0
+	bld.b\\t%1,@(0,%t0)"
+  [(set_attr "length" "4,4")])
+
+;; Store a specified bit of memory in the T bit.
+(define_insn "bldsign_m2a"
+  [(set (reg:SI T_REG)
+	(sign_extract:SI
+	    (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
+	    (const_int 1)
+	    (match_operand 1 "const_int_operand" "K03,K03")))]
+  "TARGET_SH2A && TARGET_BITOPS"
+  "@
+	bld.b\\t%1,%0
+	bld.b\\t%1,@(0,%t0)"
+  [(set_attr "length" "4,4")])
+
+;; Store a specified bit of the LSB 8 bits of a register in the T bit.
+(define_insn "bld_reg"
+  [(set (reg:SI T_REG)
+	(zero_extract:SI (match_operand:SI 0 "arith_reg_operand" "r")
+			 (const_int 1)
+			 (match_operand 1 "const_int_operand" "K03")))]
+  "TARGET_SH2A"
+  "bld\\t%1,%0")
+
+(define_insn "*bld_regqi"
+  [(set (reg:SI T_REG)
+	(zero_extract:SI (match_operand:QI 0 "arith_reg_operand" "r")
+			 (const_int 1)
+			 (match_operand 1 "const_int_operand" "K03")))]
+  "TARGET_SH2A"
+  "bld\\t%1,%0")
+
+;; Take logical and of a specified bit of memory with the T bit and
+;; store its result in the T bit.
+(define_insn "band_m2a"
+  [(set (reg:SI T_REG)
+	(and:SI (reg:SI T_REG)
+		(zero_extract:SI
+		    (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
+		    (const_int 1)
+		    (match_operand 1 "const_int_operand" "K03,K03"))))]
+  "TARGET_SH2A && TARGET_BITOPS"
+  "@
+	band.b\\t%1,%0
+	band.b\\t%1,@(0,%t0)"
+  [(set_attr "length" "4,4")])
+
+(define_insn "bandreg_m2a"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+	(and:SI (zero_extract:SI
+		    (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
+		    (const_int 1)
+		    (match_operand 2 "const_int_operand" "K03,K03"))
+        	(match_operand:SI 3 "register_operand" "r,r")))]
+  "TARGET_SH2A && TARGET_BITOPS"
+  "@
+	band.b\\t%2,%1\;movt\\t%0
+	band.b\\t%2,@(0,%t1)\;movt\\t%0"
+  [(set_attr "length" "6,6")])
+
+;; Take logical or of a specified bit of memory with the T bit and
+;; store its result in the T bit.
+(define_insn "bor_m2a"
+  [(set (reg:SI T_REG)
+	(ior:SI (reg:SI T_REG)
+		(zero_extract:SI
+		    (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
+		    (const_int 1)
+		    (match_operand 1 "const_int_operand" "K03,K03"))))]
+  "TARGET_SH2A && TARGET_BITOPS"
+  "@
+	bor.b\\t%1,%0
+	bor.b\\t%1,@(0,%t0)"
+  [(set_attr "length" "4,4")])
+
+(define_insn "borreg_m2a"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+	(ior:SI (zero_extract:SI
+		    (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
+		    (const_int 1)
+		    (match_operand 2 "const_int_operand" "K03,K03"))
+		(match_operand:SI 3 "register_operand" "=r,r")))]
+  "TARGET_SH2A && TARGET_BITOPS"
+  "@
+	bor.b\\t%2,%1\;movt\\t%0
+	bor.b\\t%2,@(0,%t1)\;movt\\t%0"
+  [(set_attr "length" "6,6")])
+
+;; Take exclusive or of a specified bit of memory with the T bit and
+;; store its result in the T bit.
+(define_insn "bxor_m2a"
+  [(set (reg:SI T_REG)
+	(xor:SI (reg:SI T_REG)
+		(zero_extract:SI
+		    (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
+		    (const_int 1)
+		    (match_operand 1 "const_int_operand" "K03,K03"))))]
+  "TARGET_SH2A && TARGET_BITOPS"
+  "@
+	bxor.b\\t%1,%0
+	bxor.b\\t%1,@(0,%t0)"
+  [(set_attr "length" "4,4")])
+
+(define_insn "bxorreg_m2a"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+	(xor:SI (zero_extract:SI
+		    (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
+		    (const_int 1)
+		    (match_operand 2 "const_int_operand" "K03,K03"))
+		(match_operand:SI 3 "register_operand" "=r,r")))]
+  "TARGET_SH2A && TARGET_BITOPS"
+  "@
+	bxor.b\\t%2,%1\;movt\\t%0
+	bxor.b\\t%2,@(0,%t1)\;movt\\t%0"
+  [(set_attr "length" "6,6")])
+
 \f
 ;; -------------------------------------------------------------------------
 ;; Peepholes
 ;; -------------------------------------------------------------------------
+;; This matches cases where the bit in a memory location is set.
+(define_peephole
+  [(set (match_operand:SI 0 "arith_reg_operand" "r")
+	(sign_extend:SI (match_operand 1 "bitwise_memory_operand" "")))
+   (set (match_dup 0)
+	(ior:SI (match_dup 0)
+	(match_operand:SI 2 "const_int_operand" "Pso")))
+   (set (match_dup 1)
+	(match_operand 3 "arith_reg_operand" "r"))]
+  "TARGET_SH2A && TARGET_BITOPS
+   && satisfies_constraint_Pso (operands[2])
+   && REGNO (operands[0]) == REGNO (operands[3])"
+  "bset.b\\t%V2,@(0,%t1)")
+
+;; This matches cases where the bit in a memory location is cleared.
+(define_peephole
+  [(set (match_operand:SI 0 "arith_reg_operand" "r")
+	(sign_extend:SI (match_operand 1 "bitwise_memory_operand" "")))
+   (set (match_dup 0)
+	(and:SI (match_dup 0)
+	(match_operand:SI 2 "const_int_operand" "Psz")))
+   (set (match_dup 1)
+	(match_operand 3 "arith_reg_operand" "r"))]
+  "TARGET_SH2A && TARGET_BITOPS
+   && satisfies_constraint_Psz (operands[2])
+   && REGNO (operands[0]) == REGNO (operands[3])"
+  "bclr.b\\t%W2,@(0,%t1)")
 
 ;; This matches cases where a stack pointer increment at the start of the
 ;; epilogue combines with a stack slot read loading the return value.
--- /gcc/config/sh/sh.opt	2007-08-02 16:19:31.000000000 +0530
+++ /gcc/config/sh/sh.opt	2008-04-02 10:06:13.000000000 +0530
@@ -212,6 +212,10 @@ mbigtable
 Target Report RejectNegative Mask(BIGTABLE)
 Generate 32-bit offsets in switch tables
 
+mbitops
+Target Report RejectNegative Mask(BITOPS)
+Generate bit instructions
+
 mbranch-cost=
 Target RejectNegative Joined UInteger Var(sh_branch_cost) Init(-1)
 Cost to assume for a branch insn
--- /gcc/testsuite/gcc.target/sh/sh2a-band.c	1970-01-01 05:30:00.000000000 +0530
+++ /gcc/testsuite/gcc.target/sh/sh2a-band.c	2008-04-02 10:07:31.000000000 +0530
@@ -0,0 +1,92 @@
+/* Testcase to check generation of a SH2A specific instruction for
+   "BAND.B #imm3, @(disp12, Rn)".  */
+/* { dg-do assemble {target sh*-*-*}}  */
+/* { dg-options "-O1 -mbitops" }  */
+/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single -m2a-single-only" }  */
+/* { dg-final { scan-assembler "band.b"} }  */
+
+volatile struct
+{
+  union
+  {
+    unsigned char BYTE;
+    struct
+    {
+      unsigned char BIT7:1;
+      unsigned char BIT6:1;
+      unsigned char BIT5:1;
+      unsigned char BIT4:1;
+      unsigned char BIT3:1;
+      unsigned char BIT2:1;
+      unsigned char BIT1:1;
+      unsigned char BIT0:1;
+    }
+    BIT;
+  }
+  ICR0;
+}
+USRSTR;
+
+volatile union t_IOR
+{
+  unsigned short WORD;
+  struct
+  {
+    unsigned char IOR15:1;
+    unsigned char IOR14:1;
+    unsigned char IOR13:1;
+    unsigned char IOR12:1;
+    unsigned char IOR11:1;
+    unsigned char IOR10:1;
+    unsigned char IOR9:1;
+    unsigned char IOR8:1;
+    unsigned char IOR7:1;
+    unsigned char IOR6:1;
+    unsigned char IOR5:1;
+    unsigned char IOR4:1;
+    unsigned char IOR3:1;
+    unsigned char IOR2:1;
+    unsigned char IOR1:1;
+    unsigned char IOR0:1;
+  }
+  BIT;
+}
+PORT;
+
+int
+main ()
+{
+  volatile unsigned char a;
+
+  /* Instruction generated is BAND.B #imm3, @(disp12, Rn)  */
+  USRSTR.ICR0.BIT.BIT3 = USRSTR.ICR0.BIT.BIT4 & USRSTR.ICR0.BIT.BIT1;
+  USRSTR.ICR0.BIT.BIT2 = USRSTR.ICR0.BIT.BIT6 & USRSTR.ICR0.BIT.BIT6;
+  USRSTR.ICR0.BIT.BIT4 = USRSTR.ICR0.BIT.BIT2 & USRSTR.ICR0.BIT.BIT4;
+  USRSTR.ICR0.BIT.BIT6 = USRSTR.ICR0.BIT.BIT1 & USRSTR.ICR0.BIT.BIT3;
+
+  a = USRSTR.ICR0.BIT.BIT0 & USRSTR.ICR0.BIT.BIT1;
+  a = USRSTR.ICR0.BIT.BIT5 & USRSTR.ICR0.BIT.BIT7;
+  a = USRSTR.ICR0.BIT.BIT2 & USRSTR.ICR0.BIT.BIT6;
+
+  PORT.BIT.IOR13 = PORT.BIT.IOR0  &  USRSTR.ICR0.BIT.BIT7;
+  PORT.BIT.IOR15 = PORT.BIT.IOR6  &  USRSTR.ICR0.BIT.BIT2;
+  PORT.BIT.IOR3  = PORT.BIT.IOR2  &  USRSTR.ICR0.BIT.BIT5;
+  PORT.BIT.IOR1  = PORT.BIT.IOR13 &  USRSTR.ICR0.BIT.BIT1;
+
+  PORT.BIT.IOR1  = PORT.BIT.IOR2  &  USRSTR.ICR0.BIT.BIT1;
+  PORT.BIT.IOR11 = PORT.BIT.IOR9  &  USRSTR.ICR0.BIT.BIT2;
+  PORT.BIT.IOR8  = PORT.BIT.IOR14 &  USRSTR.ICR0.BIT.BIT5;
+
+  PORT.BIT.IOR10 &= USRSTR.ICR0.BIT.BIT1;
+  PORT.BIT.IOR1  &= USRSTR.ICR0.BIT.BIT2;
+  PORT.BIT.IOR5  &= USRSTR.ICR0.BIT.BIT5;
+  PORT.BIT.IOR14 &= USRSTR.ICR0.BIT.BIT4;
+
+  /* Instruction generated on using size optimization option "-Os".  */
+  a = a & USRSTR.ICR0.BIT.BIT1;
+  a = a & USRSTR.ICR0.BIT.BIT4;
+  a = a & USRSTR.ICR0.BIT.BIT0;
+
+  return 0;
+}
+
--- /gcc/testsuite/gcc.target/sh/sh2a-bclrmem.c	1970-01-01 05:30:00.000000000 +0530
+++ /gcc/testsuite/gcc.target/sh/sh2a-bclrmem.c	2008-04-02 10:08:24.000000000 +0530
@@ -0,0 +1,56 @@
+/* Testcase to check generation of a SH2A specific instruction
+   "BCLR #imm3,@(disp12,Rn)".  */
+/* { dg-do assemble {target sh*-*-*}}  */
+/* { dg-options "-O1 -mbitops" }  */
+/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single -m2a-single-only" }  */
+/* { dg-final { scan-assembler "bclr"} }  */
+/* { dg-final { scan-assembler "bclr.b"} }  */
+
+volatile union un_paddr
+{
+  unsigned short WORD;
+  struct
+  {
+    unsigned char B15:1;
+    unsigned char B14:1;
+    unsigned char B13:1;
+    unsigned char B12:1;
+    unsigned char B11:1;
+    unsigned char B10:1;
+    unsigned char B9:1;
+    unsigned char B8:1;
+    unsigned char B7:1;
+    unsigned char B6:1;
+    unsigned char B5:1;
+    unsigned char B4:1;
+    unsigned char B3:1;
+    unsigned char B2:1;
+    unsigned char B1:1;
+    unsigned char B0:1;
+  }
+  BIT;
+}
+PADDR;
+
+int
+main ()
+{
+  PADDR.BIT.B0 = 0;
+  PADDR.BIT.B3 = 0;
+  PADDR.BIT.B6 = 0;
+
+  PADDR.BIT.B1 &= 0;
+  PADDR.BIT.B4 &= 0;
+  PADDR.BIT.B7 &= 0;
+
+  PADDR.BIT.B10 = 0;
+  PADDR.BIT.B13 = 0;
+  PADDR.BIT.B15 = 0;
+
+  PADDR.BIT.B9 &= 0;
+  PADDR.BIT.B12 &= 0;
+  PADDR.BIT.B14 &= 0;
+
+  return 0;
+}
+
--- /gcc/testsuite/gcc.target/sh/sh2a-bld.c	1970-01-01 05:30:00.000000000 +0530
+++ /gcc/testsuite/gcc.target/sh/sh2a-bld.c	2008-04-02 10:09:22.000000000 +0530
@@ -0,0 +1,44 @@
+/* A testcase to check generation of the following SH2A specific
+   instructions.
+
+    BLD #imm3, Rn
+    BLD.B #imm3, @(disp12, Rn)
+ */
+/* { dg-do assemble {target sh*-*-*}}  */
+/* { dg-options "-Os -mbitops" }  */
+/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single -m2a-single-only" }  */
+/* { dg-final { scan-assembler "bld"} }  */
+/* { dg-final { scan-assembler "bld.b"} }  */
+
+volatile struct
+{
+  union
+  {
+    unsigned char BYTE;
+    struct
+    {
+      unsigned char BIT7:1;
+      unsigned char BIT6:1;
+      unsigned char BIT5:1;
+      unsigned char BIT4:1;
+      unsigned char BIT3:1;
+      unsigned char BIT2:1;
+      unsigned char BIT1:1;
+      unsigned char BIT0:1;
+    }
+    BIT;
+  }
+  ICR0;
+}
+USRSTR;
+
+int
+main ()
+{
+  volatile unsigned char a, b, c;
+  USRSTR.ICR0.BIT.BIT6 &= a;
+  USRSTR.ICR0.BIT.BIT5 |= b;
+  USRSTR.ICR0.BIT.BIT4 ^= c;
+  return 0;
+}
+
--- /gcc/testsuite/gcc.target/sh/sh2a-bor.c	1970-01-01 05:30:00.000000000 +0530
+++ /gcc/testsuite/gcc.target/sh/sh2a-bor.c	2008-04-02 10:07:46.000000000 +0530
@@ -0,0 +1,92 @@
+/* Testcase to check generation of a SH2A specific instruction for
+   "BOR.B #imm3, @(disp12, Rn)".  */
+/* { dg-do assemble {target sh*-*-*}}  */
+/* { dg-options "-O1 -mbitops" } */
+/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single -m2a-single-only" }  */
+/* { dg-final { scan-assembler "bor.b"} }  */
+
+volatile struct
+{
+  union
+  {
+    unsigned char BYTE;
+    struct
+    {
+      unsigned char BIT7:1;
+      unsigned char BIT6:1;
+      unsigned char BIT5:1;
+      unsigned char BIT4:1;
+      unsigned char BIT3:1;
+      unsigned char BIT2:1;
+      unsigned char BIT1:1;
+      unsigned char BIT0:1;
+    }
+    BIT;
+  }
+  ICR0;
+}
+USRSTR;
+
+volatile union t_IOR
+{
+  unsigned short WORD;
+  struct
+  {
+    unsigned char IOR15:1;
+    unsigned char IOR14:1;
+    unsigned char IOR13:1;
+    unsigned char IOR12:1;
+    unsigned char IOR11:1;
+    unsigned char IOR10:1;
+    unsigned char IOR9:1;
+    unsigned char IOR8:1;
+    unsigned char IOR7:1;
+    unsigned char IOR6:1;
+    unsigned char IOR5:1;
+    unsigned char IOR4:1;
+    unsigned char IOR3:1;
+    unsigned char IOR2:1;
+    unsigned char IOR1:1;
+    unsigned char IOR0:1;
+  }
+  BIT;
+}
+PORT;
+
+int
+main ()
+{
+  volatile unsigned char a;
+
+  /* Instruction generated is BOR.B #imm3, @(disp12, Rn)  */
+  USRSTR.ICR0.BIT.BIT3 = USRSTR.ICR0.BIT.BIT4 | USRSTR.ICR0.BIT.BIT1;
+  USRSTR.ICR0.BIT.BIT2 = USRSTR.ICR0.BIT.BIT6 | USRSTR.ICR0.BIT.BIT6;
+  USRSTR.ICR0.BIT.BIT4 = USRSTR.ICR0.BIT.BIT2 | USRSTR.ICR0.BIT.BIT4;
+  USRSTR.ICR0.BIT.BIT6 = USRSTR.ICR0.BIT.BIT1 | USRSTR.ICR0.BIT.BIT3;
+
+  a = USRSTR.ICR0.BIT.BIT0 | USRSTR.ICR0.BIT.BIT1;
+  a = USRSTR.ICR0.BIT.BIT5 | USRSTR.ICR0.BIT.BIT7;
+  a = USRSTR.ICR0.BIT.BIT2 | USRSTR.ICR0.BIT.BIT6;
+
+  PORT.BIT.IOR13 = PORT.BIT.IOR0  |  USRSTR.ICR0.BIT.BIT7;
+  PORT.BIT.IOR15 = PORT.BIT.IOR6  |  USRSTR.ICR0.BIT.BIT2;
+  PORT.BIT.IOR3  = PORT.BIT.IOR2  |  USRSTR.ICR0.BIT.BIT5;
+  PORT.BIT.IOR1  = PORT.BIT.IOR13 |  USRSTR.ICR0.BIT.BIT1;
+
+  PORT.BIT.IOR1  = PORT.BIT.IOR2  |  USRSTR.ICR0.BIT.BIT1;
+  PORT.BIT.IOR11 = PORT.BIT.IOR9  |  USRSTR.ICR0.BIT.BIT2;
+  PORT.BIT.IOR8  = PORT.BIT.IOR14 |  USRSTR.ICR0.BIT.BIT5;
+
+  PORT.BIT.IOR10 |= USRSTR.ICR0.BIT.BIT1;
+  PORT.BIT.IOR1  |= USRSTR.ICR0.BIT.BIT2;
+  PORT.BIT.IOR5  |= USRSTR.ICR0.BIT.BIT5;
+  PORT.BIT.IOR14 |= USRSTR.ICR0.BIT.BIT4;
+
+  /* Instruction generated on using size optimization option "-Os".  */
+  a = a & USRSTR.ICR0.BIT.BIT1;
+  a = a & USRSTR.ICR0.BIT.BIT4;
+  a = a & USRSTR.ICR0.BIT.BIT0;
+
+  return 0;
+}
+
--- /gcc/testsuite/gcc.target/sh/sh2a-bsetmem.c	1970-01-01 05:30:00.000000000 +0530
+++ /gcc/testsuite/gcc.target/sh/sh2a-bsetmem.c	2008-04-02 10:08:52.000000000 +0530
@@ -0,0 +1,56 @@
+/* Testcase to check generation of a SH2A specific instruction
+   "BSET #imm3,@(disp12,Rn)".  */
+/* { dg-do assemble {target sh*-*-*}}  */
+/* { dg-options "-O1 -mbitops" }  */
+/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single -m2a-single-only" }  */
+/* { dg-final { scan-assembler "bset"} }  */
+/* { dg-final { scan-assembler "bset.b"} }  */
+
+volatile union un_paddr
+{
+  unsigned short WORD;
+  struct
+  {
+    unsigned char B15:1;
+    unsigned char B14:1;
+    unsigned char B13:1;
+    unsigned char B12:1;
+    unsigned char B11:1;
+    unsigned char B10:1;
+    unsigned char B9:1;
+    unsigned char B8:1;
+    unsigned char B7:1;
+    unsigned char B6:1;
+    unsigned char B5:1;
+    unsigned char B4:1;
+    unsigned char B3:1;
+    unsigned char B2:1;
+    unsigned char B1:1;
+    unsigned char B0:1;
+  }
+  BIT;
+}
+PADDR;
+
+int
+main ()
+{
+  PADDR.BIT.B0 = 1;
+  PADDR.BIT.B3 = 1;
+  PADDR.BIT.B6 = 1;
+
+  PADDR.BIT.B1 |= 1;
+  PADDR.BIT.B4 |= 1;
+  PADDR.BIT.B7 |= 1;
+
+  PADDR.BIT.B10 = 1;
+  PADDR.BIT.B13 = 1;
+  PADDR.BIT.B15 = 1;
+
+  PADDR.BIT.B9  |= 1;
+  PADDR.BIT.B12 |= 1;
+  PADDR.BIT.B14 |= 1;
+
+  return 0;
+}
+
--- /gcc/testsuite/gcc.target/sh/sh2a-bxor.c	1970-01-01 05:30:00.000000000 +0530
+++ /gcc/testsuite/gcc.target/sh/sh2a-bxor.c	2008-04-02 10:07:58.000000000 +0530
@@ -0,0 +1,92 @@
+/* Testcase to check generation of a SH2A specific instruction for
+   "BXOR.B #imm3, @(disp12, Rn)".  */
+/* { dg-do assemble {target sh*-*-*}}  */
+/* { dg-options "-O1 -mbitops" }  */
+/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single -m2a-single-only" }  */
+/* { dg-final { scan-assembler "bxor.b"} }  */
+
+volatile struct
+{
+  union
+  {
+    unsigned char BYTE;
+    struct
+    {
+      unsigned char BIT7:1;
+      unsigned char BIT6:1;
+      unsigned char BIT5:1;
+      unsigned char BIT4:1;
+      unsigned char BIT3:1;
+      unsigned char BIT2:1;
+      unsigned char BIT1:1;
+      unsigned char BIT0:1;
+    }
+    BIT;
+  }
+  ICR0;
+}
+USRSTR;
+
+volatile union t_IOR
+{
+  unsigned short WORD;
+  struct
+  {
+    unsigned char IOR15:1;
+    unsigned char IOR14:1;
+    unsigned char IOR13:1;
+    unsigned char IOR12:1;
+    unsigned char IOR11:1;
+    unsigned char IOR10:1;
+    unsigned char IOR9:1;
+    unsigned char IOR8:1;
+    unsigned char IOR7:1;
+    unsigned char IOR6:1;
+    unsigned char IOR5:1;
+    unsigned char IOR4:1;
+    unsigned char IOR3:1;
+    unsigned char IOR2:1;
+    unsigned char IOR1:1;
+    unsigned char IOR0:1;
+  }
+  BIT;
+}
+PORT;
+
+int
+main ()
+{
+  volatile unsigned char a;
+
+  /* Instruction generated is BXOR.B #imm3, @(disp12, Rn)  */
+  USRSTR.ICR0.BIT.BIT3 = USRSTR.ICR0.BIT.BIT4 ^ USRSTR.ICR0.BIT.BIT1;
+  USRSTR.ICR0.BIT.BIT2 = USRSTR.ICR0.BIT.BIT6 ^ USRSTR.ICR0.BIT.BIT6;
+  USRSTR.ICR0.BIT.BIT4 = USRSTR.ICR0.BIT.BIT2 ^ USRSTR.ICR0.BIT.BIT4;
+  USRSTR.ICR0.BIT.BIT6 = USRSTR.ICR0.BIT.BIT1 ^ USRSTR.ICR0.BIT.BIT3;
+
+  a = USRSTR.ICR0.BIT.BIT0 ^ USRSTR.ICR0.BIT.BIT1;
+  a = USRSTR.ICR0.BIT.BIT5 ^ USRSTR.ICR0.BIT.BIT7;
+  a = USRSTR.ICR0.BIT.BIT2 ^ USRSTR.ICR0.BIT.BIT6;
+
+  PORT.BIT.IOR13 = PORT.BIT.IOR0  ^  USRSTR.ICR0.BIT.BIT7;
+  PORT.BIT.IOR15 = PORT.BIT.IOR6  ^  USRSTR.ICR0.BIT.BIT2;
+  PORT.BIT.IOR3  = PORT.BIT.IOR2  ^  USRSTR.ICR0.BIT.BIT5;
+  PORT.BIT.IOR1  = PORT.BIT.IOR13 ^  USRSTR.ICR0.BIT.BIT1;
+
+  PORT.BIT.IOR1  = PORT.BIT.IOR2  ^  USRSTR.ICR0.BIT.BIT1;
+  PORT.BIT.IOR11 = PORT.BIT.IOR9  ^  USRSTR.ICR0.BIT.BIT2;
+  PORT.BIT.IOR8  = PORT.BIT.IOR14 ^  USRSTR.ICR0.BIT.BIT5;
+
+  PORT.BIT.IOR10 ^= USRSTR.ICR0.BIT.BIT1;
+  PORT.BIT.IOR1  ^= USRSTR.ICR0.BIT.BIT2;
+  PORT.BIT.IOR5  ^= USRSTR.ICR0.BIT.BIT5;
+  PORT.BIT.IOR14 ^= USRSTR.ICR0.BIT.BIT4;
+
+  /* Instruction generated on using size optimization option "-Os".  */
+  a = a ^ USRSTR.ICR0.BIT.BIT1;
+  a = a ^ USRSTR.ICR0.BIT.BIT4;
+  a = a ^ USRSTR.ICR0.BIT.BIT0;
+
+  return 0;
+}
+

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH,SH] Add SH2A new instructions 6/6
  2008-04-02 12:10   ` Naveen H.S.
@ 2008-04-02 13:46     ` Kaz Kojima
  2008-04-03  6:01       ` Naveen H.S.
  0 siblings, 1 reply; 14+ messages in thread
From: Kaz Kojima @ 2008-04-02 13:46 UTC (permalink / raw)
  To: naveen.hs; +Cc: gcc-patches, Prafulla.Thakare

"Naveen H.S." <naveen.hs@kpitcummins.com> wrote:
> Please find the revised patch attached "sh2a6.patch" as per the
> suggestions.

Your attachment has DOS line ends and can't be applied to
the current trunk cleanly.

> +@item -mbitops
> +@opindex mbitops
> +Enable the use of bit instructions.

  Enable the use of bit manipulation instructions on SH2A.

would be better.
Also please mention how your document changes are tested.

>	* config/sh/sh.md (*iorsi3_bset): Move the instruction above
>	iorsi3_compact.

For what purpose?

>	(bset.b, bclr.b): Define peepholes.

Use of define_peephole is deprecated.  We shouldn't add new ones.
Please use define_peephole2 instead.

One minor ChangeLog formatting issue:

>	* config/sh/sh.opt: New option bitops is added to generate bit
>	instructions.

should be

	* config/sh/sh.opt (mbitops): New option.

Regards,
	kaz

^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [PATCH,SH] Add SH2A new instructions 6/6
  2008-04-02 13:46     ` Kaz Kojima
@ 2008-04-03  6:01       ` Naveen H.S.
  2008-04-03  9:13         ` Kaz Kojima
  0 siblings, 1 reply; 14+ messages in thread
From: Naveen H.S. @ 2008-04-03  6:01 UTC (permalink / raw)
  To: Kaz Kojima; +Cc: gcc-patches, Prafulla Thakare

[-- Attachment #1: Type: text/plain, Size: 2414 bytes --]

Hi Kaz,

>> Your attachment has DOS line ends and can't be applied to
>> the current trunk cleanly.
Please find the revised patch attached "sh2a6.patch" as per the
suggestions.

>> Enable the use of bit manipulation instructions on SH2A.
>> would be better.
Done.

>> mention how your document changes are tested
The document changes were tested using makeinfo.

>> For what purpose?
The instruction '*iorsi3' is a subset of 'iorsi3_compact' and is
not getting generated as it is placed later in the order. 

>> Use of define_peephole is deprecated.  We shouldn't add new ones.
>> use define_peephole2 instead.
Done. Thanks for the suggestion.

ChangeLog
2008-04-03  Naveen.H.S  <naveen.hs@kpitcummins.com>
	
	* doc/invoke.texi: Document -mbitops for SH.

	* config/sh/constraints.md (K03, K12, Sbv, Sbw): New 
	constraints.
	* config/sh/predicates.md (bitwise_memory_operand): New
	predicate.
	* config/sh/sh.c (print_operand): Add %t operand code.
	* config/sh/sh.h (GO_IF_LEGITIMATE_INDEX): Add condition
	for SH2A.
	* config/sh/sh.md (*iorsi3_bset): Move the instruction above
	iorsi3_compact.
	(extendqisi2_compact): Add the alternative for SH2A 4-byte
	mov.b.
	(extendqihi2): Likewise.
	(movqi_i): Likewise.
	(insv): Use bset, bclr and bst instructions for SH2A if
	possible.
	(extv): Use bld instruction for SH2A if possible.
	(extzv): Likewise.
	(bclr_m2a, bclrmem_m2a, bset_m2a, bsetmem_m2a, bst_m2a, bld_m2a,
	bldsign_m2a, bld_reg, *bld_regqi, band_m2a, bandreg_m2a,
	bor_m2a, borreg_m2a, bxor_m2a, bxorreg_m2a): New insns.
	(bset.b, bclr.b): Define peepholes.
	* config/sh/sh.opt: (mbitops): New option.
	
	* gcc.target/sh/sh2a-band.c: New test.
	* gcc.target/sh/sh2a-bclrmem.c: New test.
	* gcc.target/sh/sh2a-bld.c: New test.
	* gcc.target/sh/sh2a-bor.c: New test.
	* gcc.target/sh/sh2a-bsetmem.c: New test.
	* gcc.target/sh/sh2a-bxor.c: New test.

Regards,
Naveen.H.S.
KPIT Cummins Infosystems Ltd,
Pune (INDIA) 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~	
Free download of GNU based tool-chains for Renesas' SH, H8, R8C, M16C	
and M32C Series. The following site also offers free technical support	
to its users. Visit http://www.kpitgnutools.com for details. 	
Latest versions of KPIT GNU tools were released on February 4, 2008.	
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~	

[-- Attachment #2: sh2a6.patch --]
[-- Type: application/octet-stream, Size: 29998 bytes --]

--- /gcc/doc/invoke.texi	2008-03-28 23:47:00.000000000 +0530
+++ /gcc/doc/invoke.texi	2008-04-03 09:20:26.000000000 +0530
@@ -744,7 +744,7 @@ See RS/6000 and PowerPC Options.
 -m5-compact  -m5-compact-nofpu @gol
 -mb  -ml  -mdalign  -mrelax @gol
 -mbigtable  -mfmovd  -mhitachi -mrenesas -mno-renesas -mnomacsave @gol
--mieee  -misize  -minline-ic_invalidate -mpadstruct  -mspace @gol
+-mieee  -mbitops  -misize  -minline-ic_invalidate -mpadstruct  -mspace @gol
 -mprefergot  -musermode -multcost=@var{number} -mdiv=@var{strategy} @gol
 -mdivsi3_libfunc=@var{name}  @gol
 -madjust-unroll -mindexed-addressing -mgettrcost=@var{number} -mpt-fixed @gol
@@ -13885,6 +13885,10 @@ linker option @option{-relax}.
 Use 32-bit offsets in @code{switch} tables.  The default is to use
 16-bit offsets.
 
+@item -mbitops
+@opindex mbitops
+Enable the use of bit manipulation instructions on SH2A.
+
 @item -mfmovd
 @opindex mfmovd
 Enable the use of the instruction @code{fmovd}.

--- /gcc/config/sh/constraints.md	2008-03-25 19:14:00.000000000 +0530
+++ /gcc/config/sh/constraints.md	2008-04-03 09:18:42.000000000 +0530
@@ -125,11 +125,21 @@
   (and (match_code "const_int")
        (match_test "CONST_OK_FOR_J16 (ival)")))
 
+(define_constraint "K03"
+  "An unsigned 3-bit constant, as used in SH2A bclr, bset, etc."
+  (and (match_code "const_int")
+       (match_test "ival >= 0 && ival <= 7")))
+
 (define_constraint "K08"
   "An unsigned 8-bit constant, as used in and, or, etc."
   (and (match_code "const_int")
        (match_test "ival >= 0 && ival <= 255")))
  
+(define_constraint "K12"
+  "An unsigned 8-bit constant, as used in SH2A 12-bit display."
+  (and (match_code "const_int")
+       (match_test "ival >= 0 && ival <= 4095")))
+
 (define_constraint "K16"
   "An unsigned 16-bit constant, as used in SHmedia shori."
   (and (match_code "const_int")
@@ -239,3 +249,15 @@
   "@internal"
   (and (match_test "memory_operand (op, GET_MODE (op))")
        (match_test "GET_CODE (XEXP (op, 0)) != PLUS")))
+
+(define_memory_constraint "Sbv"
+  "A memory reference, as used in SH2A bclr.b, bset.b, etc."
+  (and (match_test "MEM_P (op) && GET_MODE (op) == QImode")
+       (match_test "REG_P (XEXP (op, 0))")))
+
+(define_memory_constraint "Sbw"
+  "A memory reference, as used in SH2A bclr.b, bset.b, etc."
+  (and (match_test "MEM_P (op) && GET_MODE (op) == QImode")
+       (match_test "GET_CODE (XEXP (op, 0)) == PLUS")
+       (match_test "REG_P (XEXP (XEXP (op, 0), 0))")
+       (match_test "satisfies_constraint_K12 (XEXP (XEXP (op, 0), 1))")))

--- /gcc/config/sh/predicates.md	2007-08-02 16:19:31.000000000 +0530
+++ /gcc/config/sh/predicates.md	2008-04-03 09:18:42.000000000 +0530
@@ -789,3 +789,19 @@
     return 0;
   return arith_reg_operand (op, mode);
 })
+
+(define_predicate "bitwise_memory_operand"
+  (match_code "mem")
+{
+  if (GET_CODE (op) == MEM)
+    {
+      if (REG_P (XEXP (op, 0)))
+	return 1;
+
+      if (GET_CODE (XEXP (op, 0)) == PLUS
+	  && GET_CODE (XEXP (XEXP (op, 0), 0)) == REG
+	  && satisfies_constraint_K12 (XEXP (XEXP (op, 0), 1)))
+        return 1;
+    }
+  return 0;
+})

--- /gcc/config/sh/sh.c	2008-03-25 19:14:00.000000000 +0530
+++ /gcc/config/sh/sh.c	2008-04-03 09:18:42.000000000 +0530
@@ -683,6 +683,7 @@ print_operand_address (FILE *stream, rtx
    'U'  Likewise for {LD,ST}{HI,LO}.
    'V'  print the position of a single bit set.
    'W'  print the position of a single bit cleared.
+   't'  print a memory address which is a register.
    'u'  prints the lowest 16 bits of CONST_INT, as an unsigned value.
    'o'  output an operator.  */
 
@@ -822,6 +823,21 @@ print_operand (FILE *stream, rtx x, int 
 	  break;
 	}
       break;
+
+    case 't':
+      gcc_assert (GET_CODE (x) == MEM);
+      x = XEXP (x, 0);
+      switch (GET_CODE (x))
+	{
+	case REG:
+	case SUBREG:
+	  print_operand (stream, x, 0);
+	  break;
+	default:
+	  break;
+	}
+      break;
+
     case 'o':
       switch (GET_CODE (x))
 	{

--- /gcc/config/sh/sh.h	2008-02-29 18:16:19.000000000 +0530
+++ /gcc/config/sh/sh.h	2008-04-03 09:18:42.000000000 +0530
@@ -2449,6 +2449,12 @@ struct sh_args {
 	    else							\
 	      break;							\
 	  }								\
+	if (TARGET_SH2A)						\
+	  {								\
+	    if (GET_MODE_SIZE (MODE) == 1				\
+		&& (unsigned) INTVAL (OP) < 4096)			\
+	    goto LABEL;							\
+	  }								\
 	if (MODE_DISP_OK_4 ((OP), (MODE)))  goto LABEL;		      	\
 	if (MODE_DISP_OK_8 ((OP), (MODE)))  goto LABEL;		      	\
       }									\

--- /gcc/config/sh/sh.md	2008-03-25 19:14:00.000000000 +0530
+++ /gcc/config/sh/sh.md	2008-04-03 10:08:16.000000000 +0530
@@ -3242,6 +3242,14 @@ label:
   ""
   "")
 
+(define_insn "*iorsi3_bset"
+  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
+        (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0")
+        	(match_operand:SI 2 "const_int_operand" "Pso")))]
+  "TARGET_SH2A && satisfies_constraint_Pso (operands[2])"
+  "bset\\t%V2,%0"
+  [(set_attr "type" "arith")])
+
 (define_insn "*iorsi3_compact"
   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
 	(ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
@@ -3260,14 +3268,6 @@ label:
 	ori	%1, %2, %0"
   [(set_attr "type" "arith_media")])
 
-(define_insn "*iorsi3_bset"
-  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
-	(ior:SI (match_operand:SI 1 "arith_reg_operand" "%0")
-	(match_operand:SI 2 "const_int_operand" "Pso")))]
-  "TARGET_SH2A && satisfies_constraint_Pso (operands[2])"
-  "bset\\t%V2,%0"
-  [(set_attr "type" "arith")])
-
 (define_insn "iordi3"
   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
 	(ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
@@ -4723,7 +4723,12 @@ label:
   "@
 	exts.b	%1,%0
 	mov.b	%1,%0"
-  [(set_attr "type" "arith,load")])
+  [(set_attr "type" "arith,load")
+   (set_attr_alternative "length"
+     [(const_int 2)
+       (if_then_else
+	(ne (symbol_ref "TARGET_SH2A") (const_int 0))
+	(const_int 4) (const_int 2))])])
 
 (define_insn "*extendqisi2_media"
   [(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -4761,7 +4766,12 @@ label:
   "@
 	exts.b	%1,%0
 	mov.b	%1,%0"
-  [(set_attr "type" "arith,load")])
+  [(set_attr "type" "arith,load")
+   (set_attr_alternative "length"
+     [(const_int 2)
+       (if_then_else
+	(ne (symbol_ref "TARGET_SH2A") (const_int 0))
+	(const_int 4) (const_int 2))])])
 
 /* It would seem useful to combine the truncXi patterns into the movXi
    patterns, but unary operators are ignored when matching constraints,
@@ -5309,7 +5319,19 @@ label:
 	movt	%0
 	sts	%1,%0
 	lds	%1,%0"
- [(set_attr "type" "move,movi8,load,store,arith,prget,prset")])
+ [(set_attr "type" "move,movi8,load,store,arith,prget,prset")
+  (set_attr_alternative "length"
+     [(const_int 2)
+      (const_int 2)
+      (if_then_else
+	(ne (symbol_ref "TARGET_SH2A") (const_int 0))
+	(const_int 4) (const_int 2))
+      (if_then_else
+	(ne (symbol_ref "TARGET_SH2A") (const_int 0))
+	(const_int 4) (const_int 2))
+      (const_int 2)
+      (const_int 2)
+      (const_int 2)])])
 
 (define_insn "*movqi_media"
   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
@@ -11655,6 +11677,36 @@ mov.l\\t1f,r0\\n\\
   HOST_WIDE_INT bitsize, size, v = 0;
   rtx x = operands[3];
 
+  if (TARGET_SH2A && TARGET_BITOPS
+      && (satisfies_constraint_Sbw (operands[0])
+	  || satisfies_constraint_Sbv (operands[0]))
+      && satisfies_constraint_M (operands[1])
+      && satisfies_constraint_K03 (operands[2]))
+    {
+      if (satisfies_constraint_N (operands[3]))
+	{
+	  emit_insn (gen_bclr_m2a (operands[0], operands[2]));
+	  DONE;
+	}
+      else if (satisfies_constraint_M (operands[3]))
+	{
+	  emit_insn (gen_bset_m2a (operands[0], operands[2]));
+	  DONE;
+	}
+      else if ((REG_P (operands[3]) && REGNO (operands[3]) == T_REG)
+		&& satisfies_constraint_M (operands[1]))
+	{
+	  emit_insn (gen_bst_m2a (operands[0], operands[2]));
+	  DONE;
+	}
+      else if (REG_P (operands[3])
+	       && satisfies_constraint_M (operands[1]))
+	{
+	  emit_insn (gen_bld_reg (operands[3], const0_rtx));
+	  emit_insn (gen_bst_m2a (operands[0], operands[2]));
+	  DONE;
+	}
+    }
   /* ??? expmed doesn't care for non-register predicates.  */
   if (! memory_operand (operands[0], VOIDmode)
       || ! immediate_operand (operands[1], VOIDmode)
@@ -11732,8 +11784,19 @@ mov.l\\t1f,r0\\n\\
 	(sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
 			 (match_operand 2 "const_int_operand" "")
 			 (match_operand 3 "const_int_operand" "")))]
-  "TARGET_SH4A_ARCH"
+  "TARGET_SH4A_ARCH || TARGET_SH2A"
 {
+  if (TARGET_SH2A && TARGET_BITOPS
+      && (satisfies_constraint_Sbw (operands[1])
+	  || satisfies_constraint_Sbv (operands[1]))
+      && satisfies_constraint_M (operands[2])
+      && satisfies_constraint_K03 (operands[3]))
+   {
+      emit_insn (gen_bldsign_m2a (operands[1], operands[3]));
+      if (REGNO (operands[0]) != T_REG)
+	emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
+      DONE;
+   }
   if (TARGET_SH4A_ARCH
       && INTVAL (operands[2]) == 32
       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
@@ -11753,8 +11816,19 @@ mov.l\\t1f,r0\\n\\
 	(zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
 			 (match_operand 2 "const_int_operand" "")
 			 (match_operand 3 "const_int_operand" "")))]
-  "TARGET_SH4A_ARCH"
+  "TARGET_SH4A_ARCH || TARGET_SH2A"
 {
+  if (TARGET_SH2A && TARGET_BITOPS
+      && (satisfies_constraint_Sbw (operands[1])
+	  || satisfies_constraint_Sbv (operands[1]))
+      && satisfies_constraint_M (operands[2])
+      && satisfies_constraint_K03 (operands[3]))
+    {
+      emit_insn (gen_bld_m2a (operands[1], operands[3]));
+      if (REGNO (operands[0]) != T_REG)
+	emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
+      DONE;
+    }
   if (TARGET_SH4A_ARCH
       && INTVAL (operands[2]) == 32
       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
@@ -11769,10 +11843,235 @@ mov.l\\t1f,r0\\n\\
   FAIL;
 })
 
+;; SH2A instructions for bitwise operations.
+
+;; Clear a bit in a memory location.
+(define_insn "bclr_m2a"
+  [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
+	(and:QI
+	    (not:QI (ashift:QI (const_int 1)
+			(match_operand:QI 1 "const_int_operand" "K03,K03")))
+	    (match_dup 0)))]
+  "TARGET_SH2A && TARGET_BITOPS"
+  "@
+	bclr.b\\t%1,%0
+	bclr.b\\t%1,@(0,%t0)"
+[(set_attr "length" "4,4")])
+
+(define_insn "bclrmem_m2a"
+  [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
+        (and:QI (match_dup 0)
+                (match_operand:QI 1 "const_int_operand" "Psz,Psz")))]
+  "TARGET_SH2A && satisfies_constraint_Psz (operands[1]) && TARGET_BITOPS"
+  "@
+        bclr.b\\t%W1,%0
+        bclr.b\\t%W1,@(0,%t0)"
+  [(set_attr "length" "4,4")])
+
+;; Set a bit in a memory location.
+(define_insn "bset_m2a"
+  [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
+	(ior:QI
+	    (ashift:QI (const_int 1)
+		       (match_operand:QI 1 "const_int_operand" "K03,K03"))
+	    (match_dup 0)))]
+  "TARGET_SH2A && TARGET_BITOPS"
+  "@
+	bset.b\\t%1,%0
+	bset.b\\t%1,@(0,%t0)"
+  [(set_attr "length" "4,4")])
+
+(define_insn "bsetmem_m2a"
+  [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
+	(ior:QI (match_dup 0)
+		(match_operand:QI 1 "const_int_operand" "Pso,Pso")))]
+  "TARGET_SH2A && satisfies_constraint_Pso (operands[1]) && TARGET_BITOPS"
+  "@
+        bset.b\\t%V1,%0
+        bset.b\\t%V1,@(0,%t0)"
+  [(set_attr "length" "4,4")])
+
+;;; Transfer the contents of the T bit to a specified bit of memory.
+(define_insn "bst_m2a"
+  [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,m")
+	(if_then_else (eq (reg:SI T_REG) (const_int 0))
+	    (and:QI
+		(not:QI (ashift:QI (const_int 1)
+			(match_operand:QI 1 "const_int_operand" "K03,K03")))
+		(match_dup 0))
+	    (ior:QI
+		(ashift:QI (const_int 1) (match_dup 1))
+		(match_dup 0))))]
+  "TARGET_SH2A && TARGET_BITOPS"
+  "@
+	bst.b\\t%1,%0
+	bst.b\\t%1,@(0,%t0)"
+  [(set_attr "length" "4")])
+
+;; Store a specified bit of memory in the T bit.
+(define_insn "bld_m2a"
+  [(set (reg:SI T_REG)
+	(zero_extract:SI
+	    (match_operand:QI 0 "bitwise_memory_operand" "Sbw,Sbv")
+	    (const_int 1)
+	    (match_operand 1 "const_int_operand" "K03,K03")))]
+  "TARGET_SH2A && TARGET_BITOPS"
+  "@
+	bld.b\\t%1,%0
+	bld.b\\t%1,@(0,%t0)"
+  [(set_attr "length" "4,4")])
+
+;; Store a specified bit of memory in the T bit.
+(define_insn "bldsign_m2a"
+  [(set (reg:SI T_REG)
+	(sign_extract:SI
+	    (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
+	    (const_int 1)
+	    (match_operand 1 "const_int_operand" "K03,K03")))]
+  "TARGET_SH2A && TARGET_BITOPS"
+  "@
+	bld.b\\t%1,%0
+	bld.b\\t%1,@(0,%t0)"
+  [(set_attr "length" "4,4")])
+
+;; Store a specified bit of the LSB 8 bits of a register in the T bit.
+(define_insn "bld_reg"
+  [(set (reg:SI T_REG)
+	(zero_extract:SI (match_operand:SI 0 "arith_reg_operand" "r")
+			 (const_int 1)
+			 (match_operand 1 "const_int_operand" "K03")))]
+  "TARGET_SH2A"
+  "bld\\t%1,%0")
+
+(define_insn "*bld_regqi"
+  [(set (reg:SI T_REG)
+	(zero_extract:SI (match_operand:QI 0 "arith_reg_operand" "r")
+			 (const_int 1)
+			 (match_operand 1 "const_int_operand" "K03")))]
+  "TARGET_SH2A"
+  "bld\\t%1,%0")
+
+;; Take logical and of a specified bit of memory with the T bit and
+;; store its result in the T bit.
+(define_insn "band_m2a"
+  [(set (reg:SI T_REG)
+	(and:SI (reg:SI T_REG)
+		(zero_extract:SI
+		    (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
+		    (const_int 1)
+		    (match_operand 1 "const_int_operand" "K03,K03"))))]
+  "TARGET_SH2A && TARGET_BITOPS"
+  "@
+	band.b\\t%1,%0
+	band.b\\t%1,@(0,%t0)"
+  [(set_attr "length" "4,4")])
+
+(define_insn "bandreg_m2a"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+	(and:SI (zero_extract:SI
+		    (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
+		    (const_int 1)
+		    (match_operand 2 "const_int_operand" "K03,K03"))
+        	(match_operand:SI 3 "register_operand" "r,r")))]
+  "TARGET_SH2A && TARGET_BITOPS"
+  "@
+	band.b\\t%2,%1\;movt\\t%0
+	band.b\\t%2,@(0,%t1)\;movt\\t%0"
+  [(set_attr "length" "6,6")])
+
+;; Take logical or of a specified bit of memory with the T bit and
+;; store its result in the T bit.
+(define_insn "bor_m2a"
+  [(set (reg:SI T_REG)
+	(ior:SI (reg:SI T_REG)
+		(zero_extract:SI
+		    (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
+		    (const_int 1)
+		    (match_operand 1 "const_int_operand" "K03,K03"))))]
+  "TARGET_SH2A && TARGET_BITOPS"
+  "@
+	bor.b\\t%1,%0
+	bor.b\\t%1,@(0,%t0)"
+  [(set_attr "length" "4,4")])
+
+(define_insn "borreg_m2a"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+	(ior:SI (zero_extract:SI
+		    (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
+		    (const_int 1)
+		    (match_operand 2 "const_int_operand" "K03,K03"))
+		(match_operand:SI 3 "register_operand" "=r,r")))]
+  "TARGET_SH2A && TARGET_BITOPS"
+  "@
+	bor.b\\t%2,%1\;movt\\t%0
+	bor.b\\t%2,@(0,%t1)\;movt\\t%0"
+  [(set_attr "length" "6,6")])
+
+;; Take exclusive or of a specified bit of memory with the T bit and
+;; store its result in the T bit.
+(define_insn "bxor_m2a"
+  [(set (reg:SI T_REG)
+	(xor:SI (reg:SI T_REG)
+		(zero_extract:SI
+		    (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
+		    (const_int 1)
+		    (match_operand 1 "const_int_operand" "K03,K03"))))]
+  "TARGET_SH2A && TARGET_BITOPS"
+  "@
+	bxor.b\\t%1,%0
+	bxor.b\\t%1,@(0,%t0)"
+  [(set_attr "length" "4,4")])
+
+(define_insn "bxorreg_m2a"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+	(xor:SI (zero_extract:SI
+		    (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
+		    (const_int 1)
+		    (match_operand 2 "const_int_operand" "K03,K03"))
+		(match_operand:SI 3 "register_operand" "=r,r")))]
+  "TARGET_SH2A && TARGET_BITOPS"
+  "@
+	bxor.b\\t%2,%1\;movt\\t%0
+	bxor.b\\t%2,@(0,%t1)\;movt\\t%0"
+  [(set_attr "length" "6,6")])
+
 \f
 ;; -------------------------------------------------------------------------
 ;; Peepholes
 ;; -------------------------------------------------------------------------
+;; This matches cases where the bit in a memory location is set.
+(define_peephole2
+  [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
+	(sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
+   (set (match_dup 0)
+	(ior:SI (match_dup 0)
+	(match_operand:SI 2 "const_int_operand" "Pso,Pso")))
+   (set (match_dup 1)
+	(match_operand 3 "arith_reg_operand" "r,r"))]
+  "TARGET_SH2A && TARGET_BITOPS
+   && satisfies_constraint_Pso (operands[2])
+   && REGNO (operands[0]) == REGNO (operands[3])"
+  [(set (match_dup 1)
+        (ior:QI (match_dup 1)
+                (match_dup 2)))]
+  "")
+
+;; This matches cases where the bit in a memory location is cleared.
+(define_peephole2
+  [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
+	(sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
+   (set (match_dup 0)
+	(and:SI (match_dup 0)
+	(match_operand:SI 2 "const_int_operand" "Psz,Psz")))
+   (set (match_dup 1)
+	(match_operand 3 "arith_reg_operand" "r,r"))]
+  "TARGET_SH2A && TARGET_BITOPS
+   && satisfies_constraint_Psz (operands[2])
+   && REGNO (operands[0]) == REGNO (operands[3])"
+  [(set (match_dup 1)
+        (and:QI (match_dup 1)
+                (match_dup 2)))]
+  "")
 
 ;; This matches cases where a stack pointer increment at the start of the
 ;; epilogue combines with a stack slot read loading the return value.

--- /gcc/config/sh/sh.opt	2007-08-02 16:19:31.000000000 +0530
+++ /gcc/config/sh/sh.opt	2008-04-03 09:18:43.000000000 +0530
@@ -212,6 +212,10 @@ mbigtable
 Target Report RejectNegative Mask(BIGTABLE)
 Generate 32-bit offsets in switch tables
 
+mbitops
+Target Report RejectNegative Mask(BITOPS)
+Generate bit instructions
+
 mbranch-cost=
 Target RejectNegative Joined UInteger Var(sh_branch_cost) Init(-1)
 Cost to assume for a branch insn

--- /gcc/testsuite/gcc.target/sh/sh2a-band.c	1970-01-01 05:30:00.000000000 +0530
+++ /gcc/testsuite/gcc.target/sh/sh2a-band.c	2008-04-03 09:18:43.000000000 +0530
@@ -0,0 +1,92 @@
+/* Testcase to check generation of a SH2A specific instruction for
+   "BAND.B #imm3, @(disp12, Rn)".  */
+/* { dg-do assemble {target sh*-*-*}}  */
+/* { dg-options "-O1 -mbitops" }  */
+/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single -m2a-single-only" }  */
+/* { dg-final { scan-assembler "band.b"} }  */
+
+volatile struct
+{
+  union
+  {
+    unsigned char BYTE;
+    struct
+    {
+      unsigned char BIT7:1;
+      unsigned char BIT6:1;
+      unsigned char BIT5:1;
+      unsigned char BIT4:1;
+      unsigned char BIT3:1;
+      unsigned char BIT2:1;
+      unsigned char BIT1:1;
+      unsigned char BIT0:1;
+    }
+    BIT;
+  }
+  ICR0;
+}
+USRSTR;
+
+volatile union t_IOR
+{
+  unsigned short WORD;
+  struct
+  {
+    unsigned char IOR15:1;
+    unsigned char IOR14:1;
+    unsigned char IOR13:1;
+    unsigned char IOR12:1;
+    unsigned char IOR11:1;
+    unsigned char IOR10:1;
+    unsigned char IOR9:1;
+    unsigned char IOR8:1;
+    unsigned char IOR7:1;
+    unsigned char IOR6:1;
+    unsigned char IOR5:1;
+    unsigned char IOR4:1;
+    unsigned char IOR3:1;
+    unsigned char IOR2:1;
+    unsigned char IOR1:1;
+    unsigned char IOR0:1;
+  }
+  BIT;
+}
+PORT;
+
+int
+main ()
+{
+  volatile unsigned char a;
+
+  /* Instruction generated is BAND.B #imm3, @(disp12, Rn)  */
+  USRSTR.ICR0.BIT.BIT3 = USRSTR.ICR0.BIT.BIT4 & USRSTR.ICR0.BIT.BIT1;
+  USRSTR.ICR0.BIT.BIT2 = USRSTR.ICR0.BIT.BIT6 & USRSTR.ICR0.BIT.BIT6;
+  USRSTR.ICR0.BIT.BIT4 = USRSTR.ICR0.BIT.BIT2 & USRSTR.ICR0.BIT.BIT4;
+  USRSTR.ICR0.BIT.BIT6 = USRSTR.ICR0.BIT.BIT1 & USRSTR.ICR0.BIT.BIT3;
+
+  a = USRSTR.ICR0.BIT.BIT0 & USRSTR.ICR0.BIT.BIT1;
+  a = USRSTR.ICR0.BIT.BIT5 & USRSTR.ICR0.BIT.BIT7;
+  a = USRSTR.ICR0.BIT.BIT2 & USRSTR.ICR0.BIT.BIT6;
+
+  PORT.BIT.IOR13 = PORT.BIT.IOR0  &  USRSTR.ICR0.BIT.BIT7;
+  PORT.BIT.IOR15 = PORT.BIT.IOR6  &  USRSTR.ICR0.BIT.BIT2;
+  PORT.BIT.IOR3  = PORT.BIT.IOR2  &  USRSTR.ICR0.BIT.BIT5;
+  PORT.BIT.IOR1  = PORT.BIT.IOR13 &  USRSTR.ICR0.BIT.BIT1;
+
+  PORT.BIT.IOR1  = PORT.BIT.IOR2  &  USRSTR.ICR0.BIT.BIT1;
+  PORT.BIT.IOR11 = PORT.BIT.IOR9  &  USRSTR.ICR0.BIT.BIT2;
+  PORT.BIT.IOR8  = PORT.BIT.IOR14 &  USRSTR.ICR0.BIT.BIT5;
+
+  PORT.BIT.IOR10 &= USRSTR.ICR0.BIT.BIT1;
+  PORT.BIT.IOR1  &= USRSTR.ICR0.BIT.BIT2;
+  PORT.BIT.IOR5  &= USRSTR.ICR0.BIT.BIT5;
+  PORT.BIT.IOR14 &= USRSTR.ICR0.BIT.BIT4;
+
+  /* Instruction generated on using size optimization option "-Os".  */
+  a = a & USRSTR.ICR0.BIT.BIT1;
+  a = a & USRSTR.ICR0.BIT.BIT4;
+  a = a & USRSTR.ICR0.BIT.BIT0;
+
+  return 0;
+}
+

--- /gcc/testsuite/gcc.target/sh/sh2a-bclrmem.c	1970-01-01 05:30:00.000000000 +0530
+++ /gcc/testsuite/gcc.target/sh/sh2a-bclrmem.c	2008-04-03 10:54:05.000000000 +0530
@@ -0,0 +1,56 @@
+/* Testcase to check generation of a SH2A specific instruction
+   "BCLR #imm3,@(disp12,Rn)".  */
+/* { dg-do assemble {target sh*-*-*}}  */
+/* { dg-options "-O2 -mbitops" }  */
+/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single -m2a-single-only" }  */
+/* { dg-final { scan-assembler "bclr"} }  */
+/* { dg-final { scan-assembler "bclr.b"} }  */
+
+volatile union un_paddr
+{
+  unsigned char BYTE;
+  struct
+  {
+    unsigned char B15:1;
+    unsigned char B14:1;
+    unsigned char B13:1;
+    unsigned char B12:1;
+    unsigned char B11:1;
+    unsigned char B10:1;
+    unsigned char B9:1;
+    unsigned char B8:1;
+    unsigned char B7:1;
+    unsigned char B6:1;
+    unsigned char B5:1;
+    unsigned char B4:1;
+    unsigned char B3:1;
+    unsigned char B2:1;
+    unsigned char B1:1;
+    unsigned char B0:1;
+  }
+  BIT;
+}
+PADDR;
+
+int
+main ()
+{
+  PADDR.BIT.B0 = 0;
+  PADDR.BIT.B3 = 0;
+  PADDR.BIT.B6 = 0;
+
+  PADDR.BIT.B1 &= 0;
+  PADDR.BIT.B4 &= 0;
+  PADDR.BIT.B7 &= 0;
+
+  PADDR.BIT.B10 = 0;
+  PADDR.BIT.B13 = 0;
+  PADDR.BIT.B15 = 0;
+
+  PADDR.BIT.B9 &= 0;
+  PADDR.BIT.B12 &= 0;
+  PADDR.BIT.B14 &= 0;
+
+  return 0;
+}
+

--- /gcc/testsuite/gcc.target/sh/sh2a-bld.c	1970-01-01 05:30:00.000000000 +0530
+++ /gcc/testsuite/gcc.target/sh/sh2a-bld.c	2008-04-03 09:18:43.000000000 +0530
@@ -0,0 +1,44 @@
+/* A testcase to check generation of the following SH2A specific
+   instructions.
+
+    BLD #imm3, Rn
+    BLD.B #imm3, @(disp12, Rn)
+ */
+/* { dg-do assemble {target sh*-*-*}}  */
+/* { dg-options "-Os -mbitops" }  */
+/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single -m2a-single-only" }  */
+/* { dg-final { scan-assembler "bld"} }  */
+/* { dg-final { scan-assembler "bld.b"} }  */
+
+volatile struct
+{
+  union
+  {
+    unsigned char BYTE;
+    struct
+    {
+      unsigned char BIT7:1;
+      unsigned char BIT6:1;
+      unsigned char BIT5:1;
+      unsigned char BIT4:1;
+      unsigned char BIT3:1;
+      unsigned char BIT2:1;
+      unsigned char BIT1:1;
+      unsigned char BIT0:1;
+    }
+    BIT;
+  }
+  ICR0;
+}
+USRSTR;
+
+int
+main ()
+{
+  volatile unsigned char a, b, c;
+  USRSTR.ICR0.BIT.BIT6 &= a;
+  USRSTR.ICR0.BIT.BIT5 |= b;
+  USRSTR.ICR0.BIT.BIT4 ^= c;
+  return 0;
+}
+

--- /gcc/testsuite/gcc.target/sh/sh2a-bor.c	1970-01-01 05:30:00.000000000 +0530
+++ /gcc/testsuite/gcc.target/sh/sh2a-bor.c	2008-04-03 09:18:43.000000000 +0530
@@ -0,0 +1,92 @@
+/* Testcase to check generation of a SH2A specific instruction for
+   "BOR.B #imm3, @(disp12, Rn)".  */
+/* { dg-do assemble {target sh*-*-*}}  */
+/* { dg-options "-O1 -mbitops" } */
+/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single -m2a-single-only" }  */
+/* { dg-final { scan-assembler "bor.b"} }  */
+
+volatile struct
+{
+  union
+  {
+    unsigned char BYTE;
+    struct
+    {
+      unsigned char BIT7:1;
+      unsigned char BIT6:1;
+      unsigned char BIT5:1;
+      unsigned char BIT4:1;
+      unsigned char BIT3:1;
+      unsigned char BIT2:1;
+      unsigned char BIT1:1;
+      unsigned char BIT0:1;
+    }
+    BIT;
+  }
+  ICR0;
+}
+USRSTR;
+
+volatile union t_IOR
+{
+  unsigned short WORD;
+  struct
+  {
+    unsigned char IOR15:1;
+    unsigned char IOR14:1;
+    unsigned char IOR13:1;
+    unsigned char IOR12:1;
+    unsigned char IOR11:1;
+    unsigned char IOR10:1;
+    unsigned char IOR9:1;
+    unsigned char IOR8:1;
+    unsigned char IOR7:1;
+    unsigned char IOR6:1;
+    unsigned char IOR5:1;
+    unsigned char IOR4:1;
+    unsigned char IOR3:1;
+    unsigned char IOR2:1;
+    unsigned char IOR1:1;
+    unsigned char IOR0:1;
+  }
+  BIT;
+}
+PORT;
+
+int
+main ()
+{
+  volatile unsigned char a;
+
+  /* Instruction generated is BOR.B #imm3, @(disp12, Rn)  */
+  USRSTR.ICR0.BIT.BIT3 = USRSTR.ICR0.BIT.BIT4 | USRSTR.ICR0.BIT.BIT1;
+  USRSTR.ICR0.BIT.BIT2 = USRSTR.ICR0.BIT.BIT6 | USRSTR.ICR0.BIT.BIT6;
+  USRSTR.ICR0.BIT.BIT4 = USRSTR.ICR0.BIT.BIT2 | USRSTR.ICR0.BIT.BIT4;
+  USRSTR.ICR0.BIT.BIT6 = USRSTR.ICR0.BIT.BIT1 | USRSTR.ICR0.BIT.BIT3;
+
+  a = USRSTR.ICR0.BIT.BIT0 | USRSTR.ICR0.BIT.BIT1;
+  a = USRSTR.ICR0.BIT.BIT5 | USRSTR.ICR0.BIT.BIT7;
+  a = USRSTR.ICR0.BIT.BIT2 | USRSTR.ICR0.BIT.BIT6;
+
+  PORT.BIT.IOR13 = PORT.BIT.IOR0  |  USRSTR.ICR0.BIT.BIT7;
+  PORT.BIT.IOR15 = PORT.BIT.IOR6  |  USRSTR.ICR0.BIT.BIT2;
+  PORT.BIT.IOR3  = PORT.BIT.IOR2  |  USRSTR.ICR0.BIT.BIT5;
+  PORT.BIT.IOR1  = PORT.BIT.IOR13 |  USRSTR.ICR0.BIT.BIT1;
+
+  PORT.BIT.IOR1  = PORT.BIT.IOR2  |  USRSTR.ICR0.BIT.BIT1;
+  PORT.BIT.IOR11 = PORT.BIT.IOR9  |  USRSTR.ICR0.BIT.BIT2;
+  PORT.BIT.IOR8  = PORT.BIT.IOR14 |  USRSTR.ICR0.BIT.BIT5;
+
+  PORT.BIT.IOR10 |= USRSTR.ICR0.BIT.BIT1;
+  PORT.BIT.IOR1  |= USRSTR.ICR0.BIT.BIT2;
+  PORT.BIT.IOR5  |= USRSTR.ICR0.BIT.BIT5;
+  PORT.BIT.IOR14 |= USRSTR.ICR0.BIT.BIT4;
+
+  /* Instruction generated on using size optimization option "-Os".  */
+  a = a & USRSTR.ICR0.BIT.BIT1;
+  a = a & USRSTR.ICR0.BIT.BIT4;
+  a = a & USRSTR.ICR0.BIT.BIT0;
+
+  return 0;
+}
+

--- /gcc/testsuite/gcc.target/sh/sh2a-bsetmem.c	1970-01-01 05:30:00.000000000 +0530
+++ /gcc/testsuite/gcc.target/sh/sh2a-bsetmem.c	2008-04-03 10:53:40.000000000 +0530
@@ -0,0 +1,56 @@
+/* Testcase to check generation of a SH2A specific instruction
+   "BSET #imm3,@(disp12,Rn)".  */
+/* { dg-do assemble {target sh*-*-*}}  */
+/* { dg-options "-O2 -mbitops" }  */
+/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single -m2a-single-only" }  */
+/* { dg-final { scan-assembler "bset"} }  */
+/* { dg-final { scan-assembler "bset.b"} }  */
+
+volatile union un_paddr
+{
+  unsigned char BYTE;
+  struct
+  {
+    unsigned char B15:1;
+    unsigned char B14:1;
+    unsigned char B13:1;
+    unsigned char B12:1;
+    unsigned char B11:1;
+    unsigned char B10:1;
+    unsigned char B9:1;
+    unsigned char B8:1;
+    unsigned char B7:1;
+    unsigned char B6:1;
+    unsigned char B5:1;
+    unsigned char B4:1;
+    unsigned char B3:1;
+    unsigned char B2:1;
+    unsigned char B1:1;
+    unsigned char B0:1;
+  }
+  BIT;
+}
+PADDR;
+
+int
+main ()
+{
+  PADDR.BIT.B0 = 1;
+  PADDR.BIT.B3 = 1;
+  PADDR.BIT.B6 = 1;
+
+  PADDR.BIT.B1 |= 1;
+  PADDR.BIT.B4 |= 1;
+  PADDR.BIT.B7 |= 1;
+
+  PADDR.BIT.B10 = 1;
+  PADDR.BIT.B13 = 1;
+  PADDR.BIT.B15 = 1;
+
+  PADDR.BIT.B9  |= 1;
+  PADDR.BIT.B12 |= 1;
+  PADDR.BIT.B14 |= 1;
+
+  return 0;
+}
+

--- /gcc/testsuite/gcc.target/sh/sh2a-bxor.c	1970-01-01 05:30:00.000000000 +0530
+++ /gcc/testsuite/gcc.target/sh/sh2a-bxor.c	2008-04-03 09:18:43.000000000 +0530
@@ -0,0 +1,92 @@
+/* Testcase to check generation of a SH2A specific instruction for
+   "BXOR.B #imm3, @(disp12, Rn)".  */
+/* { dg-do assemble {target sh*-*-*}}  */
+/* { dg-options "-O1 -mbitops" }  */
+/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single -m2a-single-only" }  */
+/* { dg-final { scan-assembler "bxor.b"} }  */
+
+volatile struct
+{
+  union
+  {
+    unsigned char BYTE;
+    struct
+    {
+      unsigned char BIT7:1;
+      unsigned char BIT6:1;
+      unsigned char BIT5:1;
+      unsigned char BIT4:1;
+      unsigned char BIT3:1;
+      unsigned char BIT2:1;
+      unsigned char BIT1:1;
+      unsigned char BIT0:1;
+    }
+    BIT;
+  }
+  ICR0;
+}
+USRSTR;
+
+volatile union t_IOR
+{
+  unsigned short WORD;
+  struct
+  {
+    unsigned char IOR15:1;
+    unsigned char IOR14:1;
+    unsigned char IOR13:1;
+    unsigned char IOR12:1;
+    unsigned char IOR11:1;
+    unsigned char IOR10:1;
+    unsigned char IOR9:1;
+    unsigned char IOR8:1;
+    unsigned char IOR7:1;
+    unsigned char IOR6:1;
+    unsigned char IOR5:1;
+    unsigned char IOR4:1;
+    unsigned char IOR3:1;
+    unsigned char IOR2:1;
+    unsigned char IOR1:1;
+    unsigned char IOR0:1;
+  }
+  BIT;
+}
+PORT;
+
+int
+main ()
+{
+  volatile unsigned char a;
+
+  /* Instruction generated is BXOR.B #imm3, @(disp12, Rn)  */
+  USRSTR.ICR0.BIT.BIT3 = USRSTR.ICR0.BIT.BIT4 ^ USRSTR.ICR0.BIT.BIT1;
+  USRSTR.ICR0.BIT.BIT2 = USRSTR.ICR0.BIT.BIT6 ^ USRSTR.ICR0.BIT.BIT6;
+  USRSTR.ICR0.BIT.BIT4 = USRSTR.ICR0.BIT.BIT2 ^ USRSTR.ICR0.BIT.BIT4;
+  USRSTR.ICR0.BIT.BIT6 = USRSTR.ICR0.BIT.BIT1 ^ USRSTR.ICR0.BIT.BIT3;
+
+  a = USRSTR.ICR0.BIT.BIT0 ^ USRSTR.ICR0.BIT.BIT1;
+  a = USRSTR.ICR0.BIT.BIT5 ^ USRSTR.ICR0.BIT.BIT7;
+  a = USRSTR.ICR0.BIT.BIT2 ^ USRSTR.ICR0.BIT.BIT6;
+
+  PORT.BIT.IOR13 = PORT.BIT.IOR0  ^  USRSTR.ICR0.BIT.BIT7;
+  PORT.BIT.IOR15 = PORT.BIT.IOR6  ^  USRSTR.ICR0.BIT.BIT2;
+  PORT.BIT.IOR3  = PORT.BIT.IOR2  ^  USRSTR.ICR0.BIT.BIT5;
+  PORT.BIT.IOR1  = PORT.BIT.IOR13 ^  USRSTR.ICR0.BIT.BIT1;
+
+  PORT.BIT.IOR1  = PORT.BIT.IOR2  ^  USRSTR.ICR0.BIT.BIT1;
+  PORT.BIT.IOR11 = PORT.BIT.IOR9  ^  USRSTR.ICR0.BIT.BIT2;
+  PORT.BIT.IOR8  = PORT.BIT.IOR14 ^  USRSTR.ICR0.BIT.BIT5;
+
+  PORT.BIT.IOR10 ^= USRSTR.ICR0.BIT.BIT1;
+  PORT.BIT.IOR1  ^= USRSTR.ICR0.BIT.BIT2;
+  PORT.BIT.IOR5  ^= USRSTR.ICR0.BIT.BIT5;
+  PORT.BIT.IOR14 ^= USRSTR.ICR0.BIT.BIT4;
+
+  /* Instruction generated on using size optimization option "-Os".  */
+  a = a ^ USRSTR.ICR0.BIT.BIT1;
+  a = a ^ USRSTR.ICR0.BIT.BIT4;
+  a = a ^ USRSTR.ICR0.BIT.BIT0;
+
+  return 0;
+}
+

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH,SH] Add SH2A new instructions 6/6
  2008-04-03  6:01       ` Naveen H.S.
@ 2008-04-03  9:13         ` Kaz Kojima
  2008-04-03 10:52           ` Naveen H.S.
  0 siblings, 1 reply; 14+ messages in thread
From: Kaz Kojima @ 2008-04-03  9:13 UTC (permalink / raw)
  To: naveen.hs; +Cc: gcc-patches, Prafulla.Thakare

"Naveen H.S." <naveen.hs@kpitcummins.com> wrote:
> The instruction '*iorsi3' is a subset of 'iorsi3_compact' and is
> not getting generated as it is placed later in the order. 

Ah, I've missed it, though depending the order of insns in the .md
file is clearly the wrong way.
We should change the condition of *iorsi3_compact like as:

     * config/sh/sh.md (*iorsi3_compact): Fix condition for SH2A.

--- ORIG/trunk/gcc/config/sh/sh.md	2008-03-25 23:02:13.000000000 +0900
+++ LOCAL/trunk/gcc/config/sh/sh.md	2008-04-03 15:35:33.000000000 +0900
@@ -3246,7 +3246,8 @@ label:
   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
 	(ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
 		(match_operand:SI 2 "logical_operand" "r,K08")))]
-  "TARGET_SH1"
+  "TARGET_SH1
+   && !(TARGET_SH2A && satisfies_constraint_Pso (operands[2]))"
   "or	%2,%0"
   [(set_attr "type" "arith")])
 
though I don't test it at all.
Could you test your patch with such change?

Regards,
	kaz

^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [PATCH,SH] Add SH2A new instructions 6/6
  2008-04-03  9:13         ` Kaz Kojima
@ 2008-04-03 10:52           ` Naveen H.S.
  2008-04-03 11:14             ` Kaz Kojima
  0 siblings, 1 reply; 14+ messages in thread
From: Naveen H.S. @ 2008-04-03 10:52 UTC (permalink / raw)
  To: Kaz Kojima; +Cc: gcc-patches, Prafulla Thakare

Hi Kaz,

>> though I don't test it at all.
>> Could you test your patch with such change?

Thanks for patch.
The patch has been tested along with our patch and it works fine as
expected. The regression testing for the patch is not yet completed. 
It does not seem that there will be any extra regressions due to the 
patch. We can finally conclude on it after checking out the final
regression results (by tomorrow).

Can you please comment on changing the condition of "*andsi3_compact"
in a similar way?

Regards,
Naveen.H.S.
KPIT Cummins Infosystems Ltd,
Pune (INDIA) 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~	
Free download of GNU based tool-chains for Renesas' SH, H8, R8C, M16C	
and M32C Series. The following site also offers free technical support	
to its users. Visit http://www.kpitgnutools.com for details. 	
Latest versions of KPIT GNU tools were released on February 4, 2008.	
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~	

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH,SH] Add SH2A new instructions 6/6
  2008-04-03 10:52           ` Naveen H.S.
@ 2008-04-03 11:14             ` Kaz Kojima
  2008-04-04  9:38               ` Naveen H.S.
  0 siblings, 1 reply; 14+ messages in thread
From: Kaz Kojima @ 2008-04-03 11:14 UTC (permalink / raw)
  To: naveen.hs; +Cc: gcc-patches, Prafulla.Thakare

"Naveen H.S." <naveen.hs@kpitcummins.com> wrote:
> The patch has been tested along with our patch and it works fine as
> expected. The regression testing for the patch is not yet completed. 
> It does not seem that there will be any extra regressions due to the 
> patch. We can finally conclude on it after checking out the final
> regression results (by tomorrow).

Thanks!  I'd like to wait the result of your full testing.

> Can you please comment on changing the condition of "*andsi3_compact"
> in a similar way?

Unlike Pso constraint, Psz and K08 constraints are mutually
exclusive.  So it seems that the similar change for *andsi3_compact
isn't needed.

Regards,
	kaz

^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [PATCH,SH] Add SH2A new instructions 6/6
  2008-04-03 11:14             ` Kaz Kojima
@ 2008-04-04  9:38               ` Naveen H.S.
  2008-04-04 11:17                 ` Kaz Kojima
  0 siblings, 1 reply; 14+ messages in thread
From: Naveen H.S. @ 2008-04-04  9:38 UTC (permalink / raw)
  To: Kaz Kojima; +Cc: gcc-patches, Prafulla Thakare

Hi Kaz,

The patch is tested for all the SH2A combinations. There are no extra
regressions due to the patch.

Regards,
Naveen.H.S.
KPIT Cummins Infosystems Ltd,
Pune (INDIA) 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~	
Free download of GNU based tool-chains for Renesas' SH, H8, R8C, M16C	
and M32C Series. The following site also offers free technical support	
to its users. Visit http://www.kpitgnutools.com for details. 	
Latest versions of KPIT GNU tools were released on February 4, 2008.	
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~	

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH,SH] Add SH2A new instructions 6/6
  2008-04-04  9:38               ` Naveen H.S.
@ 2008-04-04 11:17                 ` Kaz Kojima
  2008-04-04 12:16                   ` Naveen H.S.
  0 siblings, 1 reply; 14+ messages in thread
From: Kaz Kojima @ 2008-04-04 11:17 UTC (permalink / raw)
  To: naveen.hs; +Cc: gcc-patches, Prafulla.Thakare

"Naveen H.S." <naveen.hs@kpitcummins.com> wrote:
> The patch is tested for all the SH2A combinations. There are no extra
> regressions due to the patch.

Thanks for the confirmation.  Could you please send the revised
patch and ChangeLog entry to the list?

Regards,
	kaz

^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [PATCH,SH] Add SH2A new instructions 6/6
  2008-04-04 11:17                 ` Kaz Kojima
@ 2008-04-04 12:16                   ` Naveen H.S.
  2008-04-04 12:36                     ` Kaz Kojima
  0 siblings, 1 reply; 14+ messages in thread
From: Naveen H.S. @ 2008-04-04 12:16 UTC (permalink / raw)
  To: Kaz Kojima; +Cc: gcc-patches, Prafulla Thakare

[-- Attachment #1: Type: text/plain, Size: 1858 bytes --]

Hi Kaz,

>> send the revised patch and ChangeLog entry to the list?

Thanks very much.
Please find the revised patch attached "sh2a6.patch" as per the
suggestions.

ChangeLog
2008-04-04  Naveen.H.S  <naveen.hs@kpitcummins.com>
	
	* doc/invoke.texi: Document -mbitops for SH.

	* config/sh/constraints.md (K03, K12, Sbv, Sbw): New 
	constraints.
	* config/sh/predicates.md (bitwise_memory_operand): New
	predicate.
	* config/sh/sh.c (print_operand): Add %t operand code.
	* config/sh/sh.h (GO_IF_LEGITIMATE_INDEX): Add condition
	for SH2A.
	* config/sh/sh.md (extendqisi2_compact): Add the alternative for
SH2A 
	4-byte mov.b.
	(extendqihi2): Likewise.
	(movqi_i): Likewise.
	(insv): Use bset, bclr and bst instructions for SH2A if
	possible.
	(extv): Use bld instruction for SH2A if possible.
	(extzv): Likewise.
	(bclr_m2a, bclrmem_m2a, bset_m2a, bsetmem_m2a, bst_m2a, bld_m2a,
	bldsign_m2a, bld_reg, *bld_regqi, band_m2a, bandreg_m2a,
	bor_m2a, borreg_m2a, bxor_m2a, bxorreg_m2a): New insns.
	(bset.b, bclr.b): Define peepholes.
	* config/sh/sh.opt: (mbitops): New option.
	
	* gcc.target/sh/sh2a-band.c: New test.
	* gcc.target/sh/sh2a-bclrmem.c: New test.
	* gcc.target/sh/sh2a-bld.c: New test.
	* gcc.target/sh/sh2a-bor.c: New test.
	* gcc.target/sh/sh2a-bsetmem.c: New test.
	* gcc.target/sh/sh2a-bxor.c: New test.

Regards,
Naveen.H.S.
KPIT Cummins Infosystems Ltd,
Pune (INDIA) 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~	
Free download of GNU based tool-chains for Renesas' SH, H8, R8C, M16C	
and M32C Series. The following site also offers free technical support	
to its users. Visit http://www.kpitgnutools.com for details. 	
Latest versions of KPIT GNU tools were released on February 4, 2008.	
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

[-- Attachment #2: sh2a6.patch --]
[-- Type: application/octet-stream, Size: 28957 bytes --]

--- /gcc/doc/invoke.texi	2008-03-28 23:47:00.000000000 +0530
+++ /gcc/doc/invoke.texi	2008-04-04 16:34:42.000000000 +0530
@@ -744,7 +744,7 @@ See RS/6000 and PowerPC Options.
 -m5-compact  -m5-compact-nofpu @gol
 -mb  -ml  -mdalign  -mrelax @gol
 -mbigtable  -mfmovd  -mhitachi -mrenesas -mno-renesas -mnomacsave @gol
--mieee  -misize  -minline-ic_invalidate -mpadstruct  -mspace @gol
+-mieee  -mbitops  -misize  -minline-ic_invalidate -mpadstruct  -mspace @gol
 -mprefergot  -musermode -multcost=@var{number} -mdiv=@var{strategy} @gol
 -mdivsi3_libfunc=@var{name}  @gol
 -madjust-unroll -mindexed-addressing -mgettrcost=@var{number} -mpt-fixed @gol
@@ -13885,6 +13885,10 @@ linker option @option{-relax}.
 Use 32-bit offsets in @code{switch} tables.  The default is to use
 16-bit offsets.
 
+@item -mbitops
+@opindex mbitops
+Enable the use of bit manipulation instructions on SH2A.
+
 @item -mfmovd
 @opindex mfmovd
 Enable the use of the instruction @code{fmovd}.
--- /gcc/config/sh/constraints.md	2008-03-25 19:14:00.000000000 +0530
+++ /gcc/config/sh/constraints.md	2008-04-04 16:34:42.000000000 +0530
@@ -125,11 +125,21 @@
   (and (match_code "const_int")
        (match_test "CONST_OK_FOR_J16 (ival)")))
 
+(define_constraint "K03"
+  "An unsigned 3-bit constant, as used in SH2A bclr, bset, etc."
+  (and (match_code "const_int")
+       (match_test "ival >= 0 && ival <= 7")))
+
 (define_constraint "K08"
   "An unsigned 8-bit constant, as used in and, or, etc."
   (and (match_code "const_int")
        (match_test "ival >= 0 && ival <= 255")))
  
+(define_constraint "K12"
+  "An unsigned 8-bit constant, as used in SH2A 12-bit display."
+  (and (match_code "const_int")
+       (match_test "ival >= 0 && ival <= 4095")))
+
 (define_constraint "K16"
   "An unsigned 16-bit constant, as used in SHmedia shori."
   (and (match_code "const_int")
@@ -239,3 +249,15 @@
   "@internal"
   (and (match_test "memory_operand (op, GET_MODE (op))")
        (match_test "GET_CODE (XEXP (op, 0)) != PLUS")))
+
+(define_memory_constraint "Sbv"
+  "A memory reference, as used in SH2A bclr.b, bset.b, etc."
+  (and (match_test "MEM_P (op) && GET_MODE (op) == QImode")
+       (match_test "REG_P (XEXP (op, 0))")))
+
+(define_memory_constraint "Sbw"
+  "A memory reference, as used in SH2A bclr.b, bset.b, etc."
+  (and (match_test "MEM_P (op) && GET_MODE (op) == QImode")
+       (match_test "GET_CODE (XEXP (op, 0)) == PLUS")
+       (match_test "REG_P (XEXP (XEXP (op, 0), 0))")
+       (match_test "satisfies_constraint_K12 (XEXP (XEXP (op, 0), 1))")))
--- /gcc/config/sh/predicates.md	2007-08-02 16:19:31.000000000 +0530
+++ /gcc/config/sh/predicates.md	2008-04-04 16:34:42.000000000 +0530
@@ -789,3 +789,19 @@
     return 0;
   return arith_reg_operand (op, mode);
 })
+
+(define_predicate "bitwise_memory_operand"
+  (match_code "mem")
+{
+  if (GET_CODE (op) == MEM)
+    {
+      if (REG_P (XEXP (op, 0)))
+	return 1;
+
+      if (GET_CODE (XEXP (op, 0)) == PLUS
+	  && GET_CODE (XEXP (XEXP (op, 0), 0)) == REG
+	  && satisfies_constraint_K12 (XEXP (XEXP (op, 0), 1)))
+        return 1;
+    }
+  return 0;
+})
--- /gcc/config/sh/sh.c	2008-03-25 19:14:00.000000000 +0530
+++ /gcc/config/sh/sh.c	2008-04-04 16:34:42.000000000 +0530
@@ -683,6 +683,7 @@ print_operand_address (FILE *stream, rtx
    'U'  Likewise for {LD,ST}{HI,LO}.
    'V'  print the position of a single bit set.
    'W'  print the position of a single bit cleared.
+   't'  print a memory address which is a register.
    'u'  prints the lowest 16 bits of CONST_INT, as an unsigned value.
    'o'  output an operator.  */
 
@@ -822,6 +823,21 @@ print_operand (FILE *stream, rtx x, int 
 	  break;
 	}
       break;
+
+    case 't':
+      gcc_assert (GET_CODE (x) == MEM);
+      x = XEXP (x, 0);
+      switch (GET_CODE (x))
+	{
+	case REG:
+	case SUBREG:
+	  print_operand (stream, x, 0);
+	  break;
+	default:
+	  break;
+	}
+      break;
+
     case 'o':
       switch (GET_CODE (x))
 	{
--- /gcc/config/sh/sh.h	2008-02-29 18:16:19.000000000 +0530
+++ /gcc/config/sh/sh.h	2008-04-04 16:34:42.000000000 +0530
@@ -2449,6 +2449,12 @@ struct sh_args {
 	    else							\
 	      break;							\
 	  }								\
+	if (TARGET_SH2A)						\
+	  {								\
+	    if (GET_MODE_SIZE (MODE) == 1				\
+		&& (unsigned) INTVAL (OP) < 4096)			\
+	    goto LABEL;							\
+	  }								\
 	if (MODE_DISP_OK_4 ((OP), (MODE)))  goto LABEL;		      	\
 	if (MODE_DISP_OK_8 ((OP), (MODE)))  goto LABEL;		      	\
       }									\
--- /gcc/config/sh/sh.md	2008-04-04 16:41:22.000000000 +0530
+++ /gcc/config/sh/sh.md	2008-04-04 16:42:10.000000000 +0530
@@ -4723,7 +4723,12 @@ label:
   "@
 	exts.b	%1,%0
 	mov.b	%1,%0"
-  [(set_attr "type" "arith,load")])
+  [(set_attr "type" "arith,load")
+   (set_attr_alternative "length"
+     [(const_int 2)
+       (if_then_else
+	(ne (symbol_ref "TARGET_SH2A") (const_int 0))
+	(const_int 4) (const_int 2))])])
 
 (define_insn "*extendqisi2_media"
   [(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -4761,7 +4766,12 @@ label:
   "@
 	exts.b	%1,%0
 	mov.b	%1,%0"
-  [(set_attr "type" "arith,load")])
+  [(set_attr "type" "arith,load")
+   (set_attr_alternative "length"
+     [(const_int 2)
+       (if_then_else
+	(ne (symbol_ref "TARGET_SH2A") (const_int 0))
+	(const_int 4) (const_int 2))])])
 
 /* It would seem useful to combine the truncXi patterns into the movXi
    patterns, but unary operators are ignored when matching constraints,
@@ -5309,7 +5319,19 @@ label:
 	movt	%0
 	sts	%1,%0
 	lds	%1,%0"
- [(set_attr "type" "move,movi8,load,store,arith,prget,prset")])
+ [(set_attr "type" "move,movi8,load,store,arith,prget,prset")
+  (set_attr_alternative "length"
+     [(const_int 2)
+      (const_int 2)
+      (if_then_else
+	(ne (symbol_ref "TARGET_SH2A") (const_int 0))
+	(const_int 4) (const_int 2))
+      (if_then_else
+	(ne (symbol_ref "TARGET_SH2A") (const_int 0))
+	(const_int 4) (const_int 2))
+      (const_int 2)
+      (const_int 2)
+      (const_int 2)])])
 
 (define_insn "*movqi_media"
   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
@@ -11655,6 +11677,36 @@ mov.l\\t1f,r0\\n\\
   HOST_WIDE_INT bitsize, size, v = 0;
   rtx x = operands[3];
 
+  if (TARGET_SH2A && TARGET_BITOPS
+      && (satisfies_constraint_Sbw (operands[0])
+	  || satisfies_constraint_Sbv (operands[0]))
+      && satisfies_constraint_M (operands[1])
+      && satisfies_constraint_K03 (operands[2]))
+    {
+      if (satisfies_constraint_N (operands[3]))
+	{
+	  emit_insn (gen_bclr_m2a (operands[0], operands[2]));
+	  DONE;
+	}
+      else if (satisfies_constraint_M (operands[3]))
+	{
+	  emit_insn (gen_bset_m2a (operands[0], operands[2]));
+	  DONE;
+	}
+      else if ((REG_P (operands[3]) && REGNO (operands[3]) == T_REG)
+		&& satisfies_constraint_M (operands[1]))
+	{
+	  emit_insn (gen_bst_m2a (operands[0], operands[2]));
+	  DONE;
+	}
+      else if (REG_P (operands[3])
+	       && satisfies_constraint_M (operands[1]))
+	{
+	  emit_insn (gen_bld_reg (operands[3], const0_rtx));
+	  emit_insn (gen_bst_m2a (operands[0], operands[2]));
+	  DONE;
+	}
+    }
   /* ??? expmed doesn't care for non-register predicates.  */
   if (! memory_operand (operands[0], VOIDmode)
       || ! immediate_operand (operands[1], VOIDmode)
@@ -11732,8 +11784,19 @@ mov.l\\t1f,r0\\n\\
 	(sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
 			 (match_operand 2 "const_int_operand" "")
 			 (match_operand 3 "const_int_operand" "")))]
-  "TARGET_SH4A_ARCH"
+  "TARGET_SH4A_ARCH || TARGET_SH2A"
 {
+  if (TARGET_SH2A && TARGET_BITOPS
+      && (satisfies_constraint_Sbw (operands[1])
+	  || satisfies_constraint_Sbv (operands[1]))
+      && satisfies_constraint_M (operands[2])
+      && satisfies_constraint_K03 (operands[3]))
+   {
+      emit_insn (gen_bldsign_m2a (operands[1], operands[3]));
+      if (REGNO (operands[0]) != T_REG)
+	emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
+      DONE;
+   }
   if (TARGET_SH4A_ARCH
       && INTVAL (operands[2]) == 32
       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
@@ -11753,8 +11816,19 @@ mov.l\\t1f,r0\\n\\
 	(zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
 			 (match_operand 2 "const_int_operand" "")
 			 (match_operand 3 "const_int_operand" "")))]
-  "TARGET_SH4A_ARCH"
+  "TARGET_SH4A_ARCH || TARGET_SH2A"
 {
+  if (TARGET_SH2A && TARGET_BITOPS
+      && (satisfies_constraint_Sbw (operands[1])
+	  || satisfies_constraint_Sbv (operands[1]))
+      && satisfies_constraint_M (operands[2])
+      && satisfies_constraint_K03 (operands[3]))
+    {
+      emit_insn (gen_bld_m2a (operands[1], operands[3]));
+      if (REGNO (operands[0]) != T_REG)
+	emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
+      DONE;
+    }
   if (TARGET_SH4A_ARCH
       && INTVAL (operands[2]) == 32
       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
@@ -11769,10 +11843,235 @@ mov.l\\t1f,r0\\n\\
   FAIL;
 })
 
+;; SH2A instructions for bitwise operations.
+
+;; Clear a bit in a memory location.
+(define_insn "bclr_m2a"
+  [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
+	(and:QI
+	    (not:QI (ashift:QI (const_int 1)
+			(match_operand:QI 1 "const_int_operand" "K03,K03")))
+	    (match_dup 0)))]
+  "TARGET_SH2A && TARGET_BITOPS"
+  "@
+	bclr.b\\t%1,%0
+	bclr.b\\t%1,@(0,%t0)"
+[(set_attr "length" "4,4")])
+
+(define_insn "bclrmem_m2a"
+  [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
+        (and:QI (match_dup 0)
+                (match_operand:QI 1 "const_int_operand" "Psz,Psz")))]
+  "TARGET_SH2A && satisfies_constraint_Psz (operands[1]) && TARGET_BITOPS"
+  "@
+        bclr.b\\t%W1,%0
+        bclr.b\\t%W1,@(0,%t0)"
+  [(set_attr "length" "4,4")])
+
+;; Set a bit in a memory location.
+(define_insn "bset_m2a"
+  [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
+	(ior:QI
+	    (ashift:QI (const_int 1)
+		       (match_operand:QI 1 "const_int_operand" "K03,K03"))
+	    (match_dup 0)))]
+  "TARGET_SH2A && TARGET_BITOPS"
+  "@
+	bset.b\\t%1,%0
+	bset.b\\t%1,@(0,%t0)"
+  [(set_attr "length" "4,4")])
+
+(define_insn "bsetmem_m2a"
+  [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
+	(ior:QI (match_dup 0)
+		(match_operand:QI 1 "const_int_operand" "Pso,Pso")))]
+  "TARGET_SH2A && satisfies_constraint_Pso (operands[1]) && TARGET_BITOPS"
+  "@
+        bset.b\\t%V1,%0
+        bset.b\\t%V1,@(0,%t0)"
+  [(set_attr "length" "4,4")])
+
+;;; Transfer the contents of the T bit to a specified bit of memory.
+(define_insn "bst_m2a"
+  [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,m")
+	(if_then_else (eq (reg:SI T_REG) (const_int 0))
+	    (and:QI
+		(not:QI (ashift:QI (const_int 1)
+			(match_operand:QI 1 "const_int_operand" "K03,K03")))
+		(match_dup 0))
+	    (ior:QI
+		(ashift:QI (const_int 1) (match_dup 1))
+		(match_dup 0))))]
+  "TARGET_SH2A && TARGET_BITOPS"
+  "@
+	bst.b\\t%1,%0
+	bst.b\\t%1,@(0,%t0)"
+  [(set_attr "length" "4")])
+
+;; Store a specified bit of memory in the T bit.
+(define_insn "bld_m2a"
+  [(set (reg:SI T_REG)
+	(zero_extract:SI
+	    (match_operand:QI 0 "bitwise_memory_operand" "Sbw,Sbv")
+	    (const_int 1)
+	    (match_operand 1 "const_int_operand" "K03,K03")))]
+  "TARGET_SH2A && TARGET_BITOPS"
+  "@
+	bld.b\\t%1,%0
+	bld.b\\t%1,@(0,%t0)"
+  [(set_attr "length" "4,4")])
+
+;; Store a specified bit of memory in the T bit.
+(define_insn "bldsign_m2a"
+  [(set (reg:SI T_REG)
+	(sign_extract:SI
+	    (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
+	    (const_int 1)
+	    (match_operand 1 "const_int_operand" "K03,K03")))]
+  "TARGET_SH2A && TARGET_BITOPS"
+  "@
+	bld.b\\t%1,%0
+	bld.b\\t%1,@(0,%t0)"
+  [(set_attr "length" "4,4")])
+
+;; Store a specified bit of the LSB 8 bits of a register in the T bit.
+(define_insn "bld_reg"
+  [(set (reg:SI T_REG)
+	(zero_extract:SI (match_operand:SI 0 "arith_reg_operand" "r")
+			 (const_int 1)
+			 (match_operand 1 "const_int_operand" "K03")))]
+  "TARGET_SH2A"
+  "bld\\t%1,%0")
+
+(define_insn "*bld_regqi"
+  [(set (reg:SI T_REG)
+	(zero_extract:SI (match_operand:QI 0 "arith_reg_operand" "r")
+			 (const_int 1)
+			 (match_operand 1 "const_int_operand" "K03")))]
+  "TARGET_SH2A"
+  "bld\\t%1,%0")
+
+;; Take logical and of a specified bit of memory with the T bit and
+;; store its result in the T bit.
+(define_insn "band_m2a"
+  [(set (reg:SI T_REG)
+	(and:SI (reg:SI T_REG)
+		(zero_extract:SI
+		    (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
+		    (const_int 1)
+		    (match_operand 1 "const_int_operand" "K03,K03"))))]
+  "TARGET_SH2A && TARGET_BITOPS"
+  "@
+	band.b\\t%1,%0
+	band.b\\t%1,@(0,%t0)"
+  [(set_attr "length" "4,4")])
+
+(define_insn "bandreg_m2a"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+	(and:SI (zero_extract:SI
+		    (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
+		    (const_int 1)
+		    (match_operand 2 "const_int_operand" "K03,K03"))
+        	(match_operand:SI 3 "register_operand" "r,r")))]
+  "TARGET_SH2A && TARGET_BITOPS"
+  "@
+	band.b\\t%2,%1\;movt\\t%0
+	band.b\\t%2,@(0,%t1)\;movt\\t%0"
+  [(set_attr "length" "6,6")])
+
+;; Take logical or of a specified bit of memory with the T bit and
+;; store its result in the T bit.
+(define_insn "bor_m2a"
+  [(set (reg:SI T_REG)
+	(ior:SI (reg:SI T_REG)
+		(zero_extract:SI
+		    (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
+		    (const_int 1)
+		    (match_operand 1 "const_int_operand" "K03,K03"))))]
+  "TARGET_SH2A && TARGET_BITOPS"
+  "@
+	bor.b\\t%1,%0
+	bor.b\\t%1,@(0,%t0)"
+  [(set_attr "length" "4,4")])
+
+(define_insn "borreg_m2a"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+	(ior:SI (zero_extract:SI
+		    (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
+		    (const_int 1)
+		    (match_operand 2 "const_int_operand" "K03,K03"))
+		(match_operand:SI 3 "register_operand" "=r,r")))]
+  "TARGET_SH2A && TARGET_BITOPS"
+  "@
+	bor.b\\t%2,%1\;movt\\t%0
+	bor.b\\t%2,@(0,%t1)\;movt\\t%0"
+  [(set_attr "length" "6,6")])
+
+;; Take exclusive or of a specified bit of memory with the T bit and
+;; store its result in the T bit.
+(define_insn "bxor_m2a"
+  [(set (reg:SI T_REG)
+	(xor:SI (reg:SI T_REG)
+		(zero_extract:SI
+		    (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
+		    (const_int 1)
+		    (match_operand 1 "const_int_operand" "K03,K03"))))]
+  "TARGET_SH2A && TARGET_BITOPS"
+  "@
+	bxor.b\\t%1,%0
+	bxor.b\\t%1,@(0,%t0)"
+  [(set_attr "length" "4,4")])
+
+(define_insn "bxorreg_m2a"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+	(xor:SI (zero_extract:SI
+		    (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
+		    (const_int 1)
+		    (match_operand 2 "const_int_operand" "K03,K03"))
+		(match_operand:SI 3 "register_operand" "=r,r")))]
+  "TARGET_SH2A && TARGET_BITOPS"
+  "@
+	bxor.b\\t%2,%1\;movt\\t%0
+	bxor.b\\t%2,@(0,%t1)\;movt\\t%0"
+  [(set_attr "length" "6,6")])
+
 \f
 ;; -------------------------------------------------------------------------
 ;; Peepholes
 ;; -------------------------------------------------------------------------
+;; This matches cases where the bit in a memory location is set.
+(define_peephole2
+  [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
+	(sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
+   (set (match_dup 0)
+	(ior:SI (match_dup 0)
+	(match_operand:SI 2 "const_int_operand" "Pso,Pso")))
+   (set (match_dup 1)
+	(match_operand 3 "arith_reg_operand" "r,r"))]
+  "TARGET_SH2A && TARGET_BITOPS
+   && satisfies_constraint_Pso (operands[2])
+   && REGNO (operands[0]) == REGNO (operands[3])"
+  [(set (match_dup 1)
+        (ior:QI (match_dup 1)
+                (match_dup 2)))]
+  "")
+
+;; This matches cases where the bit in a memory location is cleared.
+(define_peephole2
+  [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
+	(sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
+   (set (match_dup 0)
+	(and:SI (match_dup 0)
+	(match_operand:SI 2 "const_int_operand" "Psz,Psz")))
+   (set (match_dup 1)
+	(match_operand 3 "arith_reg_operand" "r,r"))]
+  "TARGET_SH2A && TARGET_BITOPS
+   && satisfies_constraint_Psz (operands[2])
+   && REGNO (operands[0]) == REGNO (operands[3])"
+  [(set (match_dup 1)
+        (and:QI (match_dup 1)
+                (match_dup 2)))]
+  "")
 
 ;; This matches cases where a stack pointer increment at the start of the
 ;; epilogue combines with a stack slot read loading the return value.
--- /gcc/config/sh/sh.opt	2007-08-02 16:19:31.000000000 +0530
+++ /gcc/config/sh/sh.opt	2008-04-04 16:34:43.000000000 +0530
@@ -212,6 +212,10 @@ mbigtable
 Target Report RejectNegative Mask(BIGTABLE)
 Generate 32-bit offsets in switch tables
 
+mbitops
+Target Report RejectNegative Mask(BITOPS)
+Generate bit instructions
+
 mbranch-cost=
 Target RejectNegative Joined UInteger Var(sh_branch_cost) Init(-1)
 Cost to assume for a branch insn
--- /gcc/testsuite/gcc.target/sh/sh2a-band.c	1970-01-01 05:30:00.000000000 +0530
+++ /gcc/testsuite/gcc.target/sh/sh2a-band.c	2008-04-04 16:34:43.000000000 +0530
@@ -0,0 +1,92 @@
+/* Testcase to check generation of a SH2A specific instruction for
+   "BAND.B #imm3, @(disp12, Rn)".  */
+/* { dg-do assemble {target sh*-*-*}}  */
+/* { dg-options "-O1 -mbitops" }  */
+/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single -m2a-single-only" }  */
+/* { dg-final { scan-assembler "band.b"} }  */
+
+volatile struct
+{
+  union
+  {
+    unsigned char BYTE;
+    struct
+    {
+      unsigned char BIT7:1;
+      unsigned char BIT6:1;
+      unsigned char BIT5:1;
+      unsigned char BIT4:1;
+      unsigned char BIT3:1;
+      unsigned char BIT2:1;
+      unsigned char BIT1:1;
+      unsigned char BIT0:1;
+    }
+    BIT;
+  }
+  ICR0;
+}
+USRSTR;
+
+volatile union t_IOR
+{
+  unsigned short WORD;
+  struct
+  {
+    unsigned char IOR15:1;
+    unsigned char IOR14:1;
+    unsigned char IOR13:1;
+    unsigned char IOR12:1;
+    unsigned char IOR11:1;
+    unsigned char IOR10:1;
+    unsigned char IOR9:1;
+    unsigned char IOR8:1;
+    unsigned char IOR7:1;
+    unsigned char IOR6:1;
+    unsigned char IOR5:1;
+    unsigned char IOR4:1;
+    unsigned char IOR3:1;
+    unsigned char IOR2:1;
+    unsigned char IOR1:1;
+    unsigned char IOR0:1;
+  }
+  BIT;
+}
+PORT;
+
+int
+main ()
+{
+  volatile unsigned char a;
+
+  /* Instruction generated is BAND.B #imm3, @(disp12, Rn)  */
+  USRSTR.ICR0.BIT.BIT3 = USRSTR.ICR0.BIT.BIT4 & USRSTR.ICR0.BIT.BIT1;
+  USRSTR.ICR0.BIT.BIT2 = USRSTR.ICR0.BIT.BIT6 & USRSTR.ICR0.BIT.BIT6;
+  USRSTR.ICR0.BIT.BIT4 = USRSTR.ICR0.BIT.BIT2 & USRSTR.ICR0.BIT.BIT4;
+  USRSTR.ICR0.BIT.BIT6 = USRSTR.ICR0.BIT.BIT1 & USRSTR.ICR0.BIT.BIT3;
+
+  a = USRSTR.ICR0.BIT.BIT0 & USRSTR.ICR0.BIT.BIT1;
+  a = USRSTR.ICR0.BIT.BIT5 & USRSTR.ICR0.BIT.BIT7;
+  a = USRSTR.ICR0.BIT.BIT2 & USRSTR.ICR0.BIT.BIT6;
+
+  PORT.BIT.IOR13 = PORT.BIT.IOR0  &  USRSTR.ICR0.BIT.BIT7;
+  PORT.BIT.IOR15 = PORT.BIT.IOR6  &  USRSTR.ICR0.BIT.BIT2;
+  PORT.BIT.IOR3  = PORT.BIT.IOR2  &  USRSTR.ICR0.BIT.BIT5;
+  PORT.BIT.IOR1  = PORT.BIT.IOR13 &  USRSTR.ICR0.BIT.BIT1;
+
+  PORT.BIT.IOR1  = PORT.BIT.IOR2  &  USRSTR.ICR0.BIT.BIT1;
+  PORT.BIT.IOR11 = PORT.BIT.IOR9  &  USRSTR.ICR0.BIT.BIT2;
+  PORT.BIT.IOR8  = PORT.BIT.IOR14 &  USRSTR.ICR0.BIT.BIT5;
+
+  PORT.BIT.IOR10 &= USRSTR.ICR0.BIT.BIT1;
+  PORT.BIT.IOR1  &= USRSTR.ICR0.BIT.BIT2;
+  PORT.BIT.IOR5  &= USRSTR.ICR0.BIT.BIT5;
+  PORT.BIT.IOR14 &= USRSTR.ICR0.BIT.BIT4;
+
+  /* Instruction generated on using size optimization option "-Os".  */
+  a = a & USRSTR.ICR0.BIT.BIT1;
+  a = a & USRSTR.ICR0.BIT.BIT4;
+  a = a & USRSTR.ICR0.BIT.BIT0;
+
+  return 0;
+}
+
--- /gcc/testsuite/gcc.target/sh/sh2a-bclrmem.c	1970-01-01 05:30:00.000000000 +0530
+++ /gcc/testsuite/gcc.target/sh/sh2a-bclrmem.c	2008-04-04 16:34:43.000000000 +0530
@@ -0,0 +1,56 @@
+/* Testcase to check generation of a SH2A specific instruction
+   "BCLR #imm3,@(disp12,Rn)".  */
+/* { dg-do assemble {target sh*-*-*}}  */
+/* { dg-options "-O2 -mbitops" }  */
+/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single -m2a-single-only" }  */
+/* { dg-final { scan-assembler "bclr"} }  */
+/* { dg-final { scan-assembler "bclr.b"} }  */
+
+volatile union un_paddr
+{
+  unsigned char BYTE;
+  struct
+  {
+    unsigned char B15:1;
+    unsigned char B14:1;
+    unsigned char B13:1;
+    unsigned char B12:1;
+    unsigned char B11:1;
+    unsigned char B10:1;
+    unsigned char B9:1;
+    unsigned char B8:1;
+    unsigned char B7:1;
+    unsigned char B6:1;
+    unsigned char B5:1;
+    unsigned char B4:1;
+    unsigned char B3:1;
+    unsigned char B2:1;
+    unsigned char B1:1;
+    unsigned char B0:1;
+  }
+  BIT;
+}
+PADDR;
+
+int
+main ()
+{
+  PADDR.BIT.B0 = 0;
+  PADDR.BIT.B3 = 0;
+  PADDR.BIT.B6 = 0;
+
+  PADDR.BIT.B1 &= 0;
+  PADDR.BIT.B4 &= 0;
+  PADDR.BIT.B7 &= 0;
+
+  PADDR.BIT.B10 = 0;
+  PADDR.BIT.B13 = 0;
+  PADDR.BIT.B15 = 0;
+
+  PADDR.BIT.B9 &= 0;
+  PADDR.BIT.B12 &= 0;
+  PADDR.BIT.B14 &= 0;
+
+  return 0;
+}
+
--- /gcc/testsuite/gcc.target/sh/sh2a-bld.c	1970-01-01 05:30:00.000000000 +0530
+++ /gcc/testsuite/gcc.target/sh/sh2a-bld.c	2008-04-04 16:34:43.000000000 +0530
@@ -0,0 +1,44 @@
+/* A testcase to check generation of the following SH2A specific
+   instructions.
+
+    BLD #imm3, Rn
+    BLD.B #imm3, @(disp12, Rn)
+ */
+/* { dg-do assemble {target sh*-*-*}}  */
+/* { dg-options "-Os -mbitops" }  */
+/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single -m2a-single-only" }  */
+/* { dg-final { scan-assembler "bld"} }  */
+/* { dg-final { scan-assembler "bld.b"} }  */
+
+volatile struct
+{
+  union
+  {
+    unsigned char BYTE;
+    struct
+    {
+      unsigned char BIT7:1;
+      unsigned char BIT6:1;
+      unsigned char BIT5:1;
+      unsigned char BIT4:1;
+      unsigned char BIT3:1;
+      unsigned char BIT2:1;
+      unsigned char BIT1:1;
+      unsigned char BIT0:1;
+    }
+    BIT;
+  }
+  ICR0;
+}
+USRSTR;
+
+int
+main ()
+{
+  volatile unsigned char a, b, c;
+  USRSTR.ICR0.BIT.BIT6 &= a;
+  USRSTR.ICR0.BIT.BIT5 |= b;
+  USRSTR.ICR0.BIT.BIT4 ^= c;
+  return 0;
+}
+
--- /gcc/testsuite/gcc.target/sh/sh2a-bor.c	1970-01-01 05:30:00.000000000 +0530
+++ /gcc/testsuite/gcc.target/sh/sh2a-bor.c	2008-04-04 16:34:43.000000000 +0530
@@ -0,0 +1,92 @@
+/* Testcase to check generation of a SH2A specific instruction for
+   "BOR.B #imm3, @(disp12, Rn)".  */
+/* { dg-do assemble {target sh*-*-*}}  */
+/* { dg-options "-O1 -mbitops" } */
+/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single -m2a-single-only" }  */
+/* { dg-final { scan-assembler "bor.b"} }  */
+
+volatile struct
+{
+  union
+  {
+    unsigned char BYTE;
+    struct
+    {
+      unsigned char BIT7:1;
+      unsigned char BIT6:1;
+      unsigned char BIT5:1;
+      unsigned char BIT4:1;
+      unsigned char BIT3:1;
+      unsigned char BIT2:1;
+      unsigned char BIT1:1;
+      unsigned char BIT0:1;
+    }
+    BIT;
+  }
+  ICR0;
+}
+USRSTR;
+
+volatile union t_IOR
+{
+  unsigned short WORD;
+  struct
+  {
+    unsigned char IOR15:1;
+    unsigned char IOR14:1;
+    unsigned char IOR13:1;
+    unsigned char IOR12:1;
+    unsigned char IOR11:1;
+    unsigned char IOR10:1;
+    unsigned char IOR9:1;
+    unsigned char IOR8:1;
+    unsigned char IOR7:1;
+    unsigned char IOR6:1;
+    unsigned char IOR5:1;
+    unsigned char IOR4:1;
+    unsigned char IOR3:1;
+    unsigned char IOR2:1;
+    unsigned char IOR1:1;
+    unsigned char IOR0:1;
+  }
+  BIT;
+}
+PORT;
+
+int
+main ()
+{
+  volatile unsigned char a;
+
+  /* Instruction generated is BOR.B #imm3, @(disp12, Rn)  */
+  USRSTR.ICR0.BIT.BIT3 = USRSTR.ICR0.BIT.BIT4 | USRSTR.ICR0.BIT.BIT1;
+  USRSTR.ICR0.BIT.BIT2 = USRSTR.ICR0.BIT.BIT6 | USRSTR.ICR0.BIT.BIT6;
+  USRSTR.ICR0.BIT.BIT4 = USRSTR.ICR0.BIT.BIT2 | USRSTR.ICR0.BIT.BIT4;
+  USRSTR.ICR0.BIT.BIT6 = USRSTR.ICR0.BIT.BIT1 | USRSTR.ICR0.BIT.BIT3;
+
+  a = USRSTR.ICR0.BIT.BIT0 | USRSTR.ICR0.BIT.BIT1;
+  a = USRSTR.ICR0.BIT.BIT5 | USRSTR.ICR0.BIT.BIT7;
+  a = USRSTR.ICR0.BIT.BIT2 | USRSTR.ICR0.BIT.BIT6;
+
+  PORT.BIT.IOR13 = PORT.BIT.IOR0  |  USRSTR.ICR0.BIT.BIT7;
+  PORT.BIT.IOR15 = PORT.BIT.IOR6  |  USRSTR.ICR0.BIT.BIT2;
+  PORT.BIT.IOR3  = PORT.BIT.IOR2  |  USRSTR.ICR0.BIT.BIT5;
+  PORT.BIT.IOR1  = PORT.BIT.IOR13 |  USRSTR.ICR0.BIT.BIT1;
+
+  PORT.BIT.IOR1  = PORT.BIT.IOR2  |  USRSTR.ICR0.BIT.BIT1;
+  PORT.BIT.IOR11 = PORT.BIT.IOR9  |  USRSTR.ICR0.BIT.BIT2;
+  PORT.BIT.IOR8  = PORT.BIT.IOR14 |  USRSTR.ICR0.BIT.BIT5;
+
+  PORT.BIT.IOR10 |= USRSTR.ICR0.BIT.BIT1;
+  PORT.BIT.IOR1  |= USRSTR.ICR0.BIT.BIT2;
+  PORT.BIT.IOR5  |= USRSTR.ICR0.BIT.BIT5;
+  PORT.BIT.IOR14 |= USRSTR.ICR0.BIT.BIT4;
+
+  /* Instruction generated on using size optimization option "-Os".  */
+  a = a & USRSTR.ICR0.BIT.BIT1;
+  a = a & USRSTR.ICR0.BIT.BIT4;
+  a = a & USRSTR.ICR0.BIT.BIT0;
+
+  return 0;
+}
+
--- /gcc/testsuite/gcc.target/sh/sh2a-bsetmem.c	1970-01-01 05:30:00.000000000 +0530
+++ /gcc/testsuite/gcc.target/sh/sh2a-bsetmem.c	2008-04-04 16:34:43.000000000 +0530
@@ -0,0 +1,56 @@
+/* Testcase to check generation of a SH2A specific instruction
+   "BSET #imm3,@(disp12,Rn)".  */
+/* { dg-do assemble {target sh*-*-*}}  */
+/* { dg-options "-O2 -mbitops" }  */
+/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single -m2a-single-only" }  */
+/* { dg-final { scan-assembler "bset"} }  */
+/* { dg-final { scan-assembler "bset.b"} }  */
+
+volatile union un_paddr
+{
+  unsigned char BYTE;
+  struct
+  {
+    unsigned char B15:1;
+    unsigned char B14:1;
+    unsigned char B13:1;
+    unsigned char B12:1;
+    unsigned char B11:1;
+    unsigned char B10:1;
+    unsigned char B9:1;
+    unsigned char B8:1;
+    unsigned char B7:1;
+    unsigned char B6:1;
+    unsigned char B5:1;
+    unsigned char B4:1;
+    unsigned char B3:1;
+    unsigned char B2:1;
+    unsigned char B1:1;
+    unsigned char B0:1;
+  }
+  BIT;
+}
+PADDR;
+
+int
+main ()
+{
+  PADDR.BIT.B0 = 1;
+  PADDR.BIT.B3 = 1;
+  PADDR.BIT.B6 = 1;
+
+  PADDR.BIT.B1 |= 1;
+  PADDR.BIT.B4 |= 1;
+  PADDR.BIT.B7 |= 1;
+
+  PADDR.BIT.B10 = 1;
+  PADDR.BIT.B13 = 1;
+  PADDR.BIT.B15 = 1;
+
+  PADDR.BIT.B9  |= 1;
+  PADDR.BIT.B12 |= 1;
+  PADDR.BIT.B14 |= 1;
+
+  return 0;
+}
+
--- /gcc/testsuite/gcc.target/sh/sh2a-bxor.c	1970-01-01 05:30:00.000000000 +0530
+++ /gcc/testsuite/gcc.target/sh/sh2a-bxor.c	2008-04-04 16:34:43.000000000 +0530
@@ -0,0 +1,92 @@
+/* Testcase to check generation of a SH2A specific instruction for
+   "BXOR.B #imm3, @(disp12, Rn)".  */
+/* { dg-do assemble {target sh*-*-*}}  */
+/* { dg-options "-O1 -mbitops" }  */
+/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single -m2a-single-only" }  */
+/* { dg-final { scan-assembler "bxor.b"} }  */
+
+volatile struct
+{
+  union
+  {
+    unsigned char BYTE;
+    struct
+    {
+      unsigned char BIT7:1;
+      unsigned char BIT6:1;
+      unsigned char BIT5:1;
+      unsigned char BIT4:1;
+      unsigned char BIT3:1;
+      unsigned char BIT2:1;
+      unsigned char BIT1:1;
+      unsigned char BIT0:1;
+    }
+    BIT;
+  }
+  ICR0;
+}
+USRSTR;
+
+volatile union t_IOR
+{
+  unsigned short WORD;
+  struct
+  {
+    unsigned char IOR15:1;
+    unsigned char IOR14:1;
+    unsigned char IOR13:1;
+    unsigned char IOR12:1;
+    unsigned char IOR11:1;
+    unsigned char IOR10:1;
+    unsigned char IOR9:1;
+    unsigned char IOR8:1;
+    unsigned char IOR7:1;
+    unsigned char IOR6:1;
+    unsigned char IOR5:1;
+    unsigned char IOR4:1;
+    unsigned char IOR3:1;
+    unsigned char IOR2:1;
+    unsigned char IOR1:1;
+    unsigned char IOR0:1;
+  }
+  BIT;
+}
+PORT;
+
+int
+main ()
+{
+  volatile unsigned char a;
+
+  /* Instruction generated is BXOR.B #imm3, @(disp12, Rn)  */
+  USRSTR.ICR0.BIT.BIT3 = USRSTR.ICR0.BIT.BIT4 ^ USRSTR.ICR0.BIT.BIT1;
+  USRSTR.ICR0.BIT.BIT2 = USRSTR.ICR0.BIT.BIT6 ^ USRSTR.ICR0.BIT.BIT6;
+  USRSTR.ICR0.BIT.BIT4 = USRSTR.ICR0.BIT.BIT2 ^ USRSTR.ICR0.BIT.BIT4;
+  USRSTR.ICR0.BIT.BIT6 = USRSTR.ICR0.BIT.BIT1 ^ USRSTR.ICR0.BIT.BIT3;
+
+  a = USRSTR.ICR0.BIT.BIT0 ^ USRSTR.ICR0.BIT.BIT1;
+  a = USRSTR.ICR0.BIT.BIT5 ^ USRSTR.ICR0.BIT.BIT7;
+  a = USRSTR.ICR0.BIT.BIT2 ^ USRSTR.ICR0.BIT.BIT6;
+
+  PORT.BIT.IOR13 = PORT.BIT.IOR0  ^  USRSTR.ICR0.BIT.BIT7;
+  PORT.BIT.IOR15 = PORT.BIT.IOR6  ^  USRSTR.ICR0.BIT.BIT2;
+  PORT.BIT.IOR3  = PORT.BIT.IOR2  ^  USRSTR.ICR0.BIT.BIT5;
+  PORT.BIT.IOR1  = PORT.BIT.IOR13 ^  USRSTR.ICR0.BIT.BIT1;
+
+  PORT.BIT.IOR1  = PORT.BIT.IOR2  ^  USRSTR.ICR0.BIT.BIT1;
+  PORT.BIT.IOR11 = PORT.BIT.IOR9  ^  USRSTR.ICR0.BIT.BIT2;
+  PORT.BIT.IOR8  = PORT.BIT.IOR14 ^  USRSTR.ICR0.BIT.BIT5;
+
+  PORT.BIT.IOR10 ^= USRSTR.ICR0.BIT.BIT1;
+  PORT.BIT.IOR1  ^= USRSTR.ICR0.BIT.BIT2;
+  PORT.BIT.IOR5  ^= USRSTR.ICR0.BIT.BIT5;
+  PORT.BIT.IOR14 ^= USRSTR.ICR0.BIT.BIT4;
+
+  /* Instruction generated on using size optimization option "-Os".  */
+  a = a ^ USRSTR.ICR0.BIT.BIT1;
+  a = a ^ USRSTR.ICR0.BIT.BIT4;
+  a = a ^ USRSTR.ICR0.BIT.BIT0;
+
+  return 0;
+}
+

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH,SH] Add SH2A new instructions 6/6
  2008-04-04 12:16                   ` Naveen H.S.
@ 2008-04-04 12:36                     ` Kaz Kojima
  2008-04-04 13:16                       ` Naveen H.S.
  0 siblings, 1 reply; 14+ messages in thread
From: Kaz Kojima @ 2008-04-04 12:36 UTC (permalink / raw)
  To: naveen.hs; +Cc: gcc-patches, Prafulla.Thakare

"Naveen H.S." <naveen.hs@kpitcummins.com> wrote:
> Please find the revised patch attached "sh2a6.patch" as per the
> suggestions.

It looks that the revised one and ChangeLog don't include
the hunks for *iorsi3_compact.  Could you add them?
It'd be better to record the tested patch as is.

Regards,
	kaz

^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [PATCH,SH] Add SH2A new instructions 6/6
  2008-04-04 12:36                     ` Kaz Kojima
@ 2008-04-04 13:16                       ` Naveen H.S.
  2008-04-04 13:38                         ` Kaz Kojima
  0 siblings, 1 reply; 14+ messages in thread
From: Naveen H.S. @ 2008-04-04 13:16 UTC (permalink / raw)
  To: Kaz Kojima; +Cc: gcc-patches, Prafulla Thakare

[-- Attachment #1: Type: text/plain, Size: 1893 bytes --]

Hi Kaz,

>> Could you add them?
>> It'd be better to record the tested patch as is.

Please find the revised patch attached "sh2a6.patch".

ChangeLog
2008-04-04  Naveen.H.S  <naveen.hs@kpitcummins.com>
	
	* doc/invoke.texi: Document -mbitops for SH.

	* config/sh/constraints.md (K03, K12, Sbv, Sbw): New 
	constraints.
	* config/sh/predicates.md (bitwise_memory_operand): New
	predicate.
	* config/sh/sh.c (print_operand): Add %t operand code.
	* config/sh/sh.h (GO_IF_LEGITIMATE_INDEX): Add condition
	for SH2A.
	* config/sh/sh.md (*iorsi3_compact): Fix condition for SH2A.
	(extendqisi2_compact): Add the alternative for SH2A 4-byte
	mov.b.
	(extendqihi2): Likewise.
	(movqi_i): Likewise.
	(insv): Use bset, bclr and bst instructions for SH2A if
	possible.
	(extv): Use bld instruction for SH2A if possible.
	(extzv): Likewise.
	(bclr_m2a, bclrmem_m2a, bset_m2a, bsetmem_m2a, bst_m2a, bld_m2a,
	bldsign_m2a, bld_reg, *bld_regqi, band_m2a, bandreg_m2a,
	bor_m2a, borreg_m2a, bxor_m2a, bxorreg_m2a): New insns.
	(bset.b, bclr.b): Define peepholes.
	* config/sh/sh.opt: (mbitops): New option.
	
	* gcc.target/sh/sh2a-band.c: New test.
	* gcc.target/sh/sh2a-bclrmem.c: New test.
	* gcc.target/sh/sh2a-bld.c: New test.
	* gcc.target/sh/sh2a-bor.c: New test.
	* gcc.target/sh/sh2a-bsetmem.c: New test.
	* gcc.target/sh/sh2a-bxor.c: New test.

Regards,
Naveen.H.S.
KPIT Cummins Infosystems Ltd,
Pune (INDIA) 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~	
Free download of GNU based tool-chains for Renesas' SH, H8, R8C, M16C	
and M32C Series. The following site also offers free technical support	
to its users. Visit http://www.kpitgnutools.com for details. 	
Latest versions of KPIT GNU tools were released on February 4, 2008.	
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Regards,
	kaz

[-- Attachment #2: sh2a6.patch --]
[-- Type: application/octet-stream, Size: 29295 bytes --]

--- /gcc/doc/invoke.texi	2008-03-28 23:47:00.000000000 +0530
+++ /gcc/doc/invoke.texi	2008-04-04 16:34:42.000000000 +0530
@@ -744,7 +744,7 @@ See RS/6000 and PowerPC Options.
 -m5-compact  -m5-compact-nofpu @gol
 -mb  -ml  -mdalign  -mrelax @gol
 -mbigtable  -mfmovd  -mhitachi -mrenesas -mno-renesas -mnomacsave @gol
--mieee  -misize  -minline-ic_invalidate -mpadstruct  -mspace @gol
+-mieee  -mbitops  -misize  -minline-ic_invalidate -mpadstruct  -mspace @gol
 -mprefergot  -musermode -multcost=@var{number} -mdiv=@var{strategy} @gol
 -mdivsi3_libfunc=@var{name}  @gol
 -madjust-unroll -mindexed-addressing -mgettrcost=@var{number} -mpt-fixed @gol
@@ -13885,6 +13885,10 @@ linker option @option{-relax}.
 Use 32-bit offsets in @code{switch} tables.  The default is to use
 16-bit offsets.
 
+@item -mbitops
+@opindex mbitops
+Enable the use of bit manipulation instructions on SH2A.
+
 @item -mfmovd
 @opindex mfmovd
 Enable the use of the instruction @code{fmovd}.
--- /gcc/config/sh/constraints.md	2008-03-25 19:14:00.000000000 +0530
+++ /gcc/config/sh/constraints.md	2008-04-04 16:34:42.000000000 +0530
@@ -125,11 +125,21 @@
   (and (match_code "const_int")
        (match_test "CONST_OK_FOR_J16 (ival)")))
 
+(define_constraint "K03"
+  "An unsigned 3-bit constant, as used in SH2A bclr, bset, etc."
+  (and (match_code "const_int")
+       (match_test "ival >= 0 && ival <= 7")))
+
 (define_constraint "K08"
   "An unsigned 8-bit constant, as used in and, or, etc."
   (and (match_code "const_int")
        (match_test "ival >= 0 && ival <= 255")))
  
+(define_constraint "K12"
+  "An unsigned 8-bit constant, as used in SH2A 12-bit display."
+  (and (match_code "const_int")
+       (match_test "ival >= 0 && ival <= 4095")))
+
 (define_constraint "K16"
   "An unsigned 16-bit constant, as used in SHmedia shori."
   (and (match_code "const_int")
@@ -239,3 +249,15 @@
   "@internal"
   (and (match_test "memory_operand (op, GET_MODE (op))")
        (match_test "GET_CODE (XEXP (op, 0)) != PLUS")))
+
+(define_memory_constraint "Sbv"
+  "A memory reference, as used in SH2A bclr.b, bset.b, etc."
+  (and (match_test "MEM_P (op) && GET_MODE (op) == QImode")
+       (match_test "REG_P (XEXP (op, 0))")))
+
+(define_memory_constraint "Sbw"
+  "A memory reference, as used in SH2A bclr.b, bset.b, etc."
+  (and (match_test "MEM_P (op) && GET_MODE (op) == QImode")
+       (match_test "GET_CODE (XEXP (op, 0)) == PLUS")
+       (match_test "REG_P (XEXP (XEXP (op, 0), 0))")
+       (match_test "satisfies_constraint_K12 (XEXP (XEXP (op, 0), 1))")))
--- /gcc/config/sh/predicates.md	2007-08-02 16:19:31.000000000 +0530
+++ /gcc/config/sh/predicates.md	2008-04-04 16:34:42.000000000 +0530
@@ -789,3 +789,19 @@
     return 0;
   return arith_reg_operand (op, mode);
 })
+
+(define_predicate "bitwise_memory_operand"
+  (match_code "mem")
+{
+  if (GET_CODE (op) == MEM)
+    {
+      if (REG_P (XEXP (op, 0)))
+	return 1;
+
+      if (GET_CODE (XEXP (op, 0)) == PLUS
+	  && GET_CODE (XEXP (XEXP (op, 0), 0)) == REG
+	  && satisfies_constraint_K12 (XEXP (XEXP (op, 0), 1)))
+        return 1;
+    }
+  return 0;
+})
--- /gcc/config/sh/sh.c	2008-03-25 19:14:00.000000000 +0530
+++ /gcc/config/sh/sh.c	2008-04-04 16:34:42.000000000 +0530
@@ -683,6 +683,7 @@ print_operand_address (FILE *stream, rtx
    'U'  Likewise for {LD,ST}{HI,LO}.
    'V'  print the position of a single bit set.
    'W'  print the position of a single bit cleared.
+   't'  print a memory address which is a register.
    'u'  prints the lowest 16 bits of CONST_INT, as an unsigned value.
    'o'  output an operator.  */
 
@@ -822,6 +823,21 @@ print_operand (FILE *stream, rtx x, int 
 	  break;
 	}
       break;
+
+    case 't':
+      gcc_assert (GET_CODE (x) == MEM);
+      x = XEXP (x, 0);
+      switch (GET_CODE (x))
+	{
+	case REG:
+	case SUBREG:
+	  print_operand (stream, x, 0);
+	  break;
+	default:
+	  break;
+	}
+      break;
+
     case 'o':
       switch (GET_CODE (x))
 	{
--- /gcc/config/sh/sh.h	2008-02-29 18:16:19.000000000 +0530
+++ /gcc/config/sh/sh.h	2008-04-04 16:34:42.000000000 +0530
@@ -2449,6 +2449,12 @@ struct sh_args {
 	    else							\
 	      break;							\
 	  }								\
+	if (TARGET_SH2A)						\
+	  {								\
+	    if (GET_MODE_SIZE (MODE) == 1				\
+		&& (unsigned) INTVAL (OP) < 4096)			\
+	    goto LABEL;							\
+	  }								\
 	if (MODE_DISP_OK_4 ((OP), (MODE)))  goto LABEL;		      	\
 	if (MODE_DISP_OK_8 ((OP), (MODE)))  goto LABEL;		      	\
       }									\
--- /gcc/config/sh/sh.md	2008-04-04 16:41:22.000000000 +0530
+++ /gcc/config/sh/sh.md	2008-04-04 18:00:23.000000000 +0530
@@ -3246,7 +3246,8 @@ label:
   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
 	(ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
 		(match_operand:SI 2 "logical_operand" "r,K08")))]
-  "TARGET_SH1"
+  "TARGET_SH1
+   && !(TARGET_SH2A && satisfies_constraint_Pso (operands[2]))"
   "or	%2,%0"
   [(set_attr "type" "arith")])
 
@@ -4723,7 +4724,12 @@ label:
   "@
 	exts.b	%1,%0
 	mov.b	%1,%0"
-  [(set_attr "type" "arith,load")])
+  [(set_attr "type" "arith,load")
+   (set_attr_alternative "length"
+     [(const_int 2)
+       (if_then_else
+	(ne (symbol_ref "TARGET_SH2A") (const_int 0))
+	(const_int 4) (const_int 2))])])
 
 (define_insn "*extendqisi2_media"
   [(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -4761,7 +4767,12 @@ label:
   "@
 	exts.b	%1,%0
 	mov.b	%1,%0"
-  [(set_attr "type" "arith,load")])
+  [(set_attr "type" "arith,load")
+   (set_attr_alternative "length"
+     [(const_int 2)
+       (if_then_else
+	(ne (symbol_ref "TARGET_SH2A") (const_int 0))
+	(const_int 4) (const_int 2))])])
 
 /* It would seem useful to combine the truncXi patterns into the movXi
    patterns, but unary operators are ignored when matching constraints,
@@ -5309,7 +5320,19 @@ label:
 	movt	%0
 	sts	%1,%0
 	lds	%1,%0"
- [(set_attr "type" "move,movi8,load,store,arith,prget,prset")])
+ [(set_attr "type" "move,movi8,load,store,arith,prget,prset")
+  (set_attr_alternative "length"
+     [(const_int 2)
+      (const_int 2)
+      (if_then_else
+	(ne (symbol_ref "TARGET_SH2A") (const_int 0))
+	(const_int 4) (const_int 2))
+      (if_then_else
+	(ne (symbol_ref "TARGET_SH2A") (const_int 0))
+	(const_int 4) (const_int 2))
+      (const_int 2)
+      (const_int 2)
+      (const_int 2)])])
 
 (define_insn "*movqi_media"
   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
@@ -11655,6 +11678,36 @@ mov.l\\t1f,r0\\n\\
   HOST_WIDE_INT bitsize, size, v = 0;
   rtx x = operands[3];
 
+  if (TARGET_SH2A && TARGET_BITOPS
+      && (satisfies_constraint_Sbw (operands[0])
+	  || satisfies_constraint_Sbv (operands[0]))
+      && satisfies_constraint_M (operands[1])
+      && satisfies_constraint_K03 (operands[2]))
+    {
+      if (satisfies_constraint_N (operands[3]))
+	{
+	  emit_insn (gen_bclr_m2a (operands[0], operands[2]));
+	  DONE;
+	}
+      else if (satisfies_constraint_M (operands[3]))
+	{
+	  emit_insn (gen_bset_m2a (operands[0], operands[2]));
+	  DONE;
+	}
+      else if ((REG_P (operands[3]) && REGNO (operands[3]) == T_REG)
+		&& satisfies_constraint_M (operands[1]))
+	{
+	  emit_insn (gen_bst_m2a (operands[0], operands[2]));
+	  DONE;
+	}
+      else if (REG_P (operands[3])
+	       && satisfies_constraint_M (operands[1]))
+	{
+	  emit_insn (gen_bld_reg (operands[3], const0_rtx));
+	  emit_insn (gen_bst_m2a (operands[0], operands[2]));
+	  DONE;
+	}
+    }
   /* ??? expmed doesn't care for non-register predicates.  */
   if (! memory_operand (operands[0], VOIDmode)
       || ! immediate_operand (operands[1], VOIDmode)
@@ -11732,8 +11785,19 @@ mov.l\\t1f,r0\\n\\
 	(sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
 			 (match_operand 2 "const_int_operand" "")
 			 (match_operand 3 "const_int_operand" "")))]
-  "TARGET_SH4A_ARCH"
+  "TARGET_SH4A_ARCH || TARGET_SH2A"
 {
+  if (TARGET_SH2A && TARGET_BITOPS
+      && (satisfies_constraint_Sbw (operands[1])
+	  || satisfies_constraint_Sbv (operands[1]))
+      && satisfies_constraint_M (operands[2])
+      && satisfies_constraint_K03 (operands[3]))
+   {
+      emit_insn (gen_bldsign_m2a (operands[1], operands[3]));
+      if (REGNO (operands[0]) != T_REG)
+	emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
+      DONE;
+   }
   if (TARGET_SH4A_ARCH
       && INTVAL (operands[2]) == 32
       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
@@ -11753,8 +11817,19 @@ mov.l\\t1f,r0\\n\\
 	(zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
 			 (match_operand 2 "const_int_operand" "")
 			 (match_operand 3 "const_int_operand" "")))]
-  "TARGET_SH4A_ARCH"
+  "TARGET_SH4A_ARCH || TARGET_SH2A"
 {
+  if (TARGET_SH2A && TARGET_BITOPS
+      && (satisfies_constraint_Sbw (operands[1])
+	  || satisfies_constraint_Sbv (operands[1]))
+      && satisfies_constraint_M (operands[2])
+      && satisfies_constraint_K03 (operands[3]))
+    {
+      emit_insn (gen_bld_m2a (operands[1], operands[3]));
+      if (REGNO (operands[0]) != T_REG)
+	emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
+      DONE;
+    }
   if (TARGET_SH4A_ARCH
       && INTVAL (operands[2]) == 32
       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
@@ -11769,10 +11844,235 @@ mov.l\\t1f,r0\\n\\
   FAIL;
 })
 
+;; SH2A instructions for bitwise operations.
+
+;; Clear a bit in a memory location.
+(define_insn "bclr_m2a"
+  [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
+	(and:QI
+	    (not:QI (ashift:QI (const_int 1)
+			(match_operand:QI 1 "const_int_operand" "K03,K03")))
+	    (match_dup 0)))]
+  "TARGET_SH2A && TARGET_BITOPS"
+  "@
+	bclr.b\\t%1,%0
+	bclr.b\\t%1,@(0,%t0)"
+[(set_attr "length" "4,4")])
+
+(define_insn "bclrmem_m2a"
+  [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
+        (and:QI (match_dup 0)
+                (match_operand:QI 1 "const_int_operand" "Psz,Psz")))]
+  "TARGET_SH2A && satisfies_constraint_Psz (operands[1]) && TARGET_BITOPS"
+  "@
+        bclr.b\\t%W1,%0
+        bclr.b\\t%W1,@(0,%t0)"
+  [(set_attr "length" "4,4")])
+
+;; Set a bit in a memory location.
+(define_insn "bset_m2a"
+  [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
+	(ior:QI
+	    (ashift:QI (const_int 1)
+		       (match_operand:QI 1 "const_int_operand" "K03,K03"))
+	    (match_dup 0)))]
+  "TARGET_SH2A && TARGET_BITOPS"
+  "@
+	bset.b\\t%1,%0
+	bset.b\\t%1,@(0,%t0)"
+  [(set_attr "length" "4,4")])
+
+(define_insn "bsetmem_m2a"
+  [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
+	(ior:QI (match_dup 0)
+		(match_operand:QI 1 "const_int_operand" "Pso,Pso")))]
+  "TARGET_SH2A && satisfies_constraint_Pso (operands[1]) && TARGET_BITOPS"
+  "@
+        bset.b\\t%V1,%0
+        bset.b\\t%V1,@(0,%t0)"
+  [(set_attr "length" "4,4")])
+
+;;; Transfer the contents of the T bit to a specified bit of memory.
+(define_insn "bst_m2a"
+  [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,m")
+	(if_then_else (eq (reg:SI T_REG) (const_int 0))
+	    (and:QI
+		(not:QI (ashift:QI (const_int 1)
+			(match_operand:QI 1 "const_int_operand" "K03,K03")))
+		(match_dup 0))
+	    (ior:QI
+		(ashift:QI (const_int 1) (match_dup 1))
+		(match_dup 0))))]
+  "TARGET_SH2A && TARGET_BITOPS"
+  "@
+	bst.b\\t%1,%0
+	bst.b\\t%1,@(0,%t0)"
+  [(set_attr "length" "4")])
+
+;; Store a specified bit of memory in the T bit.
+(define_insn "bld_m2a"
+  [(set (reg:SI T_REG)
+	(zero_extract:SI
+	    (match_operand:QI 0 "bitwise_memory_operand" "Sbw,Sbv")
+	    (const_int 1)
+	    (match_operand 1 "const_int_operand" "K03,K03")))]
+  "TARGET_SH2A && TARGET_BITOPS"
+  "@
+	bld.b\\t%1,%0
+	bld.b\\t%1,@(0,%t0)"
+  [(set_attr "length" "4,4")])
+
+;; Store a specified bit of memory in the T bit.
+(define_insn "bldsign_m2a"
+  [(set (reg:SI T_REG)
+	(sign_extract:SI
+	    (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
+	    (const_int 1)
+	    (match_operand 1 "const_int_operand" "K03,K03")))]
+  "TARGET_SH2A && TARGET_BITOPS"
+  "@
+	bld.b\\t%1,%0
+	bld.b\\t%1,@(0,%t0)"
+  [(set_attr "length" "4,4")])
+
+;; Store a specified bit of the LSB 8 bits of a register in the T bit.
+(define_insn "bld_reg"
+  [(set (reg:SI T_REG)
+	(zero_extract:SI (match_operand:SI 0 "arith_reg_operand" "r")
+			 (const_int 1)
+			 (match_operand 1 "const_int_operand" "K03")))]
+  "TARGET_SH2A"
+  "bld\\t%1,%0")
+
+(define_insn "*bld_regqi"
+  [(set (reg:SI T_REG)
+	(zero_extract:SI (match_operand:QI 0 "arith_reg_operand" "r")
+			 (const_int 1)
+			 (match_operand 1 "const_int_operand" "K03")))]
+  "TARGET_SH2A"
+  "bld\\t%1,%0")
+
+;; Take logical and of a specified bit of memory with the T bit and
+;; store its result in the T bit.
+(define_insn "band_m2a"
+  [(set (reg:SI T_REG)
+	(and:SI (reg:SI T_REG)
+		(zero_extract:SI
+		    (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
+		    (const_int 1)
+		    (match_operand 1 "const_int_operand" "K03,K03"))))]
+  "TARGET_SH2A && TARGET_BITOPS"
+  "@
+	band.b\\t%1,%0
+	band.b\\t%1,@(0,%t0)"
+  [(set_attr "length" "4,4")])
+
+(define_insn "bandreg_m2a"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+	(and:SI (zero_extract:SI
+		    (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
+		    (const_int 1)
+		    (match_operand 2 "const_int_operand" "K03,K03"))
+        	(match_operand:SI 3 "register_operand" "r,r")))]
+  "TARGET_SH2A && TARGET_BITOPS"
+  "@
+	band.b\\t%2,%1\;movt\\t%0
+	band.b\\t%2,@(0,%t1)\;movt\\t%0"
+  [(set_attr "length" "6,6")])
+
+;; Take logical or of a specified bit of memory with the T bit and
+;; store its result in the T bit.
+(define_insn "bor_m2a"
+  [(set (reg:SI T_REG)
+	(ior:SI (reg:SI T_REG)
+		(zero_extract:SI
+		    (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
+		    (const_int 1)
+		    (match_operand 1 "const_int_operand" "K03,K03"))))]
+  "TARGET_SH2A && TARGET_BITOPS"
+  "@
+	bor.b\\t%1,%0
+	bor.b\\t%1,@(0,%t0)"
+  [(set_attr "length" "4,4")])
+
+(define_insn "borreg_m2a"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+	(ior:SI (zero_extract:SI
+		    (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
+		    (const_int 1)
+		    (match_operand 2 "const_int_operand" "K03,K03"))
+		(match_operand:SI 3 "register_operand" "=r,r")))]
+  "TARGET_SH2A && TARGET_BITOPS"
+  "@
+	bor.b\\t%2,%1\;movt\\t%0
+	bor.b\\t%2,@(0,%t1)\;movt\\t%0"
+  [(set_attr "length" "6,6")])
+
+;; Take exclusive or of a specified bit of memory with the T bit and
+;; store its result in the T bit.
+(define_insn "bxor_m2a"
+  [(set (reg:SI T_REG)
+	(xor:SI (reg:SI T_REG)
+		(zero_extract:SI
+		    (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
+		    (const_int 1)
+		    (match_operand 1 "const_int_operand" "K03,K03"))))]
+  "TARGET_SH2A && TARGET_BITOPS"
+  "@
+	bxor.b\\t%1,%0
+	bxor.b\\t%1,@(0,%t0)"
+  [(set_attr "length" "4,4")])
+
+(define_insn "bxorreg_m2a"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+	(xor:SI (zero_extract:SI
+		    (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
+		    (const_int 1)
+		    (match_operand 2 "const_int_operand" "K03,K03"))
+		(match_operand:SI 3 "register_operand" "=r,r")))]
+  "TARGET_SH2A && TARGET_BITOPS"
+  "@
+	bxor.b\\t%2,%1\;movt\\t%0
+	bxor.b\\t%2,@(0,%t1)\;movt\\t%0"
+  [(set_attr "length" "6,6")])
+
 \f
 ;; -------------------------------------------------------------------------
 ;; Peepholes
 ;; -------------------------------------------------------------------------
+;; This matches cases where the bit in a memory location is set.
+(define_peephole2
+  [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
+	(sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
+   (set (match_dup 0)
+	(ior:SI (match_dup 0)
+	(match_operand:SI 2 "const_int_operand" "Pso,Pso")))
+   (set (match_dup 1)
+	(match_operand 3 "arith_reg_operand" "r,r"))]
+  "TARGET_SH2A && TARGET_BITOPS
+   && satisfies_constraint_Pso (operands[2])
+   && REGNO (operands[0]) == REGNO (operands[3])"
+  [(set (match_dup 1)
+        (ior:QI (match_dup 1)
+                (match_dup 2)))]
+  "")
+
+;; This matches cases where the bit in a memory location is cleared.
+(define_peephole2
+  [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
+	(sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
+   (set (match_dup 0)
+	(and:SI (match_dup 0)
+	(match_operand:SI 2 "const_int_operand" "Psz,Psz")))
+   (set (match_dup 1)
+	(match_operand 3 "arith_reg_operand" "r,r"))]
+  "TARGET_SH2A && TARGET_BITOPS
+   && satisfies_constraint_Psz (operands[2])
+   && REGNO (operands[0]) == REGNO (operands[3])"
+  [(set (match_dup 1)
+        (and:QI (match_dup 1)
+                (match_dup 2)))]
+  "")
 
 ;; This matches cases where a stack pointer increment at the start of the
 ;; epilogue combines with a stack slot read loading the return value.
--- /gcc/config/sh/sh.opt	2007-08-02 16:19:31.000000000 +0530
+++ /gcc/config/sh/sh.opt	2008-04-04 16:34:43.000000000 +0530
@@ -212,6 +212,10 @@ mbigtable
 Target Report RejectNegative Mask(BIGTABLE)
 Generate 32-bit offsets in switch tables
 
+mbitops
+Target Report RejectNegative Mask(BITOPS)
+Generate bit instructions
+
 mbranch-cost=
 Target RejectNegative Joined UInteger Var(sh_branch_cost) Init(-1)
 Cost to assume for a branch insn
--- /gcc/testsuite/gcc.target/sh/sh2a-band.c	1970-01-01 05:30:00.000000000 +0530
+++ /gcc/testsuite/gcc.target/sh/sh2a-band.c	2008-04-04 16:34:43.000000000 +0530
@@ -0,0 +1,92 @@
+/* Testcase to check generation of a SH2A specific instruction for
+   "BAND.B #imm3, @(disp12, Rn)".  */
+/* { dg-do assemble {target sh*-*-*}}  */
+/* { dg-options "-O1 -mbitops" }  */
+/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single -m2a-single-only" }  */
+/* { dg-final { scan-assembler "band.b"} }  */
+
+volatile struct
+{
+  union
+  {
+    unsigned char BYTE;
+    struct
+    {
+      unsigned char BIT7:1;
+      unsigned char BIT6:1;
+      unsigned char BIT5:1;
+      unsigned char BIT4:1;
+      unsigned char BIT3:1;
+      unsigned char BIT2:1;
+      unsigned char BIT1:1;
+      unsigned char BIT0:1;
+    }
+    BIT;
+  }
+  ICR0;
+}
+USRSTR;
+
+volatile union t_IOR
+{
+  unsigned short WORD;
+  struct
+  {
+    unsigned char IOR15:1;
+    unsigned char IOR14:1;
+    unsigned char IOR13:1;
+    unsigned char IOR12:1;
+    unsigned char IOR11:1;
+    unsigned char IOR10:1;
+    unsigned char IOR9:1;
+    unsigned char IOR8:1;
+    unsigned char IOR7:1;
+    unsigned char IOR6:1;
+    unsigned char IOR5:1;
+    unsigned char IOR4:1;
+    unsigned char IOR3:1;
+    unsigned char IOR2:1;
+    unsigned char IOR1:1;
+    unsigned char IOR0:1;
+  }
+  BIT;
+}
+PORT;
+
+int
+main ()
+{
+  volatile unsigned char a;
+
+  /* Instruction generated is BAND.B #imm3, @(disp12, Rn)  */
+  USRSTR.ICR0.BIT.BIT3 = USRSTR.ICR0.BIT.BIT4 & USRSTR.ICR0.BIT.BIT1;
+  USRSTR.ICR0.BIT.BIT2 = USRSTR.ICR0.BIT.BIT6 & USRSTR.ICR0.BIT.BIT6;
+  USRSTR.ICR0.BIT.BIT4 = USRSTR.ICR0.BIT.BIT2 & USRSTR.ICR0.BIT.BIT4;
+  USRSTR.ICR0.BIT.BIT6 = USRSTR.ICR0.BIT.BIT1 & USRSTR.ICR0.BIT.BIT3;
+
+  a = USRSTR.ICR0.BIT.BIT0 & USRSTR.ICR0.BIT.BIT1;
+  a = USRSTR.ICR0.BIT.BIT5 & USRSTR.ICR0.BIT.BIT7;
+  a = USRSTR.ICR0.BIT.BIT2 & USRSTR.ICR0.BIT.BIT6;
+
+  PORT.BIT.IOR13 = PORT.BIT.IOR0  &  USRSTR.ICR0.BIT.BIT7;
+  PORT.BIT.IOR15 = PORT.BIT.IOR6  &  USRSTR.ICR0.BIT.BIT2;
+  PORT.BIT.IOR3  = PORT.BIT.IOR2  &  USRSTR.ICR0.BIT.BIT5;
+  PORT.BIT.IOR1  = PORT.BIT.IOR13 &  USRSTR.ICR0.BIT.BIT1;
+
+  PORT.BIT.IOR1  = PORT.BIT.IOR2  &  USRSTR.ICR0.BIT.BIT1;
+  PORT.BIT.IOR11 = PORT.BIT.IOR9  &  USRSTR.ICR0.BIT.BIT2;
+  PORT.BIT.IOR8  = PORT.BIT.IOR14 &  USRSTR.ICR0.BIT.BIT5;
+
+  PORT.BIT.IOR10 &= USRSTR.ICR0.BIT.BIT1;
+  PORT.BIT.IOR1  &= USRSTR.ICR0.BIT.BIT2;
+  PORT.BIT.IOR5  &= USRSTR.ICR0.BIT.BIT5;
+  PORT.BIT.IOR14 &= USRSTR.ICR0.BIT.BIT4;
+
+  /* Instruction generated on using size optimization option "-Os".  */
+  a = a & USRSTR.ICR0.BIT.BIT1;
+  a = a & USRSTR.ICR0.BIT.BIT4;
+  a = a & USRSTR.ICR0.BIT.BIT0;
+
+  return 0;
+}
+
--- /gcc/testsuite/gcc.target/sh/sh2a-bclrmem.c	1970-01-01 05:30:00.000000000 +0530
+++ /gcc/testsuite/gcc.target/sh/sh2a-bclrmem.c	2008-04-04 16:34:43.000000000 +0530
@@ -0,0 +1,56 @@
+/* Testcase to check generation of a SH2A specific instruction
+   "BCLR #imm3,@(disp12,Rn)".  */
+/* { dg-do assemble {target sh*-*-*}}  */
+/* { dg-options "-O2 -mbitops" }  */
+/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single -m2a-single-only" }  */
+/* { dg-final { scan-assembler "bclr"} }  */
+/* { dg-final { scan-assembler "bclr.b"} }  */
+
+volatile union un_paddr
+{
+  unsigned char BYTE;
+  struct
+  {
+    unsigned char B15:1;
+    unsigned char B14:1;
+    unsigned char B13:1;
+    unsigned char B12:1;
+    unsigned char B11:1;
+    unsigned char B10:1;
+    unsigned char B9:1;
+    unsigned char B8:1;
+    unsigned char B7:1;
+    unsigned char B6:1;
+    unsigned char B5:1;
+    unsigned char B4:1;
+    unsigned char B3:1;
+    unsigned char B2:1;
+    unsigned char B1:1;
+    unsigned char B0:1;
+  }
+  BIT;
+}
+PADDR;
+
+int
+main ()
+{
+  PADDR.BIT.B0 = 0;
+  PADDR.BIT.B3 = 0;
+  PADDR.BIT.B6 = 0;
+
+  PADDR.BIT.B1 &= 0;
+  PADDR.BIT.B4 &= 0;
+  PADDR.BIT.B7 &= 0;
+
+  PADDR.BIT.B10 = 0;
+  PADDR.BIT.B13 = 0;
+  PADDR.BIT.B15 = 0;
+
+  PADDR.BIT.B9 &= 0;
+  PADDR.BIT.B12 &= 0;
+  PADDR.BIT.B14 &= 0;
+
+  return 0;
+}
+
--- /gcc/testsuite/gcc.target/sh/sh2a-bld.c	1970-01-01 05:30:00.000000000 +0530
+++ /gcc/testsuite/gcc.target/sh/sh2a-bld.c	2008-04-04 16:34:43.000000000 +0530
@@ -0,0 +1,44 @@
+/* A testcase to check generation of the following SH2A specific
+   instructions.
+
+    BLD #imm3, Rn
+    BLD.B #imm3, @(disp12, Rn)
+ */
+/* { dg-do assemble {target sh*-*-*}}  */
+/* { dg-options "-Os -mbitops" }  */
+/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single -m2a-single-only" }  */
+/* { dg-final { scan-assembler "bld"} }  */
+/* { dg-final { scan-assembler "bld.b"} }  */
+
+volatile struct
+{
+  union
+  {
+    unsigned char BYTE;
+    struct
+    {
+      unsigned char BIT7:1;
+      unsigned char BIT6:1;
+      unsigned char BIT5:1;
+      unsigned char BIT4:1;
+      unsigned char BIT3:1;
+      unsigned char BIT2:1;
+      unsigned char BIT1:1;
+      unsigned char BIT0:1;
+    }
+    BIT;
+  }
+  ICR0;
+}
+USRSTR;
+
+int
+main ()
+{
+  volatile unsigned char a, b, c;
+  USRSTR.ICR0.BIT.BIT6 &= a;
+  USRSTR.ICR0.BIT.BIT5 |= b;
+  USRSTR.ICR0.BIT.BIT4 ^= c;
+  return 0;
+}
+
--- /gcc/testsuite/gcc.target/sh/sh2a-bor.c	1970-01-01 05:30:00.000000000 +0530
+++ /gcc/testsuite/gcc.target/sh/sh2a-bor.c	2008-04-04 16:34:43.000000000 +0530
@@ -0,0 +1,92 @@
+/* Testcase to check generation of a SH2A specific instruction for
+   "BOR.B #imm3, @(disp12, Rn)".  */
+/* { dg-do assemble {target sh*-*-*}}  */
+/* { dg-options "-O1 -mbitops" } */
+/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single -m2a-single-only" }  */
+/* { dg-final { scan-assembler "bor.b"} }  */
+
+volatile struct
+{
+  union
+  {
+    unsigned char BYTE;
+    struct
+    {
+      unsigned char BIT7:1;
+      unsigned char BIT6:1;
+      unsigned char BIT5:1;
+      unsigned char BIT4:1;
+      unsigned char BIT3:1;
+      unsigned char BIT2:1;
+      unsigned char BIT1:1;
+      unsigned char BIT0:1;
+    }
+    BIT;
+  }
+  ICR0;
+}
+USRSTR;
+
+volatile union t_IOR
+{
+  unsigned short WORD;
+  struct
+  {
+    unsigned char IOR15:1;
+    unsigned char IOR14:1;
+    unsigned char IOR13:1;
+    unsigned char IOR12:1;
+    unsigned char IOR11:1;
+    unsigned char IOR10:1;
+    unsigned char IOR9:1;
+    unsigned char IOR8:1;
+    unsigned char IOR7:1;
+    unsigned char IOR6:1;
+    unsigned char IOR5:1;
+    unsigned char IOR4:1;
+    unsigned char IOR3:1;
+    unsigned char IOR2:1;
+    unsigned char IOR1:1;
+    unsigned char IOR0:1;
+  }
+  BIT;
+}
+PORT;
+
+int
+main ()
+{
+  volatile unsigned char a;
+
+  /* Instruction generated is BOR.B #imm3, @(disp12, Rn)  */
+  USRSTR.ICR0.BIT.BIT3 = USRSTR.ICR0.BIT.BIT4 | USRSTR.ICR0.BIT.BIT1;
+  USRSTR.ICR0.BIT.BIT2 = USRSTR.ICR0.BIT.BIT6 | USRSTR.ICR0.BIT.BIT6;
+  USRSTR.ICR0.BIT.BIT4 = USRSTR.ICR0.BIT.BIT2 | USRSTR.ICR0.BIT.BIT4;
+  USRSTR.ICR0.BIT.BIT6 = USRSTR.ICR0.BIT.BIT1 | USRSTR.ICR0.BIT.BIT3;
+
+  a = USRSTR.ICR0.BIT.BIT0 | USRSTR.ICR0.BIT.BIT1;
+  a = USRSTR.ICR0.BIT.BIT5 | USRSTR.ICR0.BIT.BIT7;
+  a = USRSTR.ICR0.BIT.BIT2 | USRSTR.ICR0.BIT.BIT6;
+
+  PORT.BIT.IOR13 = PORT.BIT.IOR0  |  USRSTR.ICR0.BIT.BIT7;
+  PORT.BIT.IOR15 = PORT.BIT.IOR6  |  USRSTR.ICR0.BIT.BIT2;
+  PORT.BIT.IOR3  = PORT.BIT.IOR2  |  USRSTR.ICR0.BIT.BIT5;
+  PORT.BIT.IOR1  = PORT.BIT.IOR13 |  USRSTR.ICR0.BIT.BIT1;
+
+  PORT.BIT.IOR1  = PORT.BIT.IOR2  |  USRSTR.ICR0.BIT.BIT1;
+  PORT.BIT.IOR11 = PORT.BIT.IOR9  |  USRSTR.ICR0.BIT.BIT2;
+  PORT.BIT.IOR8  = PORT.BIT.IOR14 |  USRSTR.ICR0.BIT.BIT5;
+
+  PORT.BIT.IOR10 |= USRSTR.ICR0.BIT.BIT1;
+  PORT.BIT.IOR1  |= USRSTR.ICR0.BIT.BIT2;
+  PORT.BIT.IOR5  |= USRSTR.ICR0.BIT.BIT5;
+  PORT.BIT.IOR14 |= USRSTR.ICR0.BIT.BIT4;
+
+  /* Instruction generated on using size optimization option "-Os".  */
+  a = a & USRSTR.ICR0.BIT.BIT1;
+  a = a & USRSTR.ICR0.BIT.BIT4;
+  a = a & USRSTR.ICR0.BIT.BIT0;
+
+  return 0;
+}
+
--- /gcc/testsuite/gcc.target/sh/sh2a-bsetmem.c	1970-01-01 05:30:00.000000000 +0530
+++ /gcc/testsuite/gcc.target/sh/sh2a-bsetmem.c	2008-04-04 16:34:43.000000000 +0530
@@ -0,0 +1,56 @@
+/* Testcase to check generation of a SH2A specific instruction
+   "BSET #imm3,@(disp12,Rn)".  */
+/* { dg-do assemble {target sh*-*-*}}  */
+/* { dg-options "-O2 -mbitops" }  */
+/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single -m2a-single-only" }  */
+/* { dg-final { scan-assembler "bset"} }  */
+/* { dg-final { scan-assembler "bset.b"} }  */
+
+volatile union un_paddr
+{
+  unsigned char BYTE;
+  struct
+  {
+    unsigned char B15:1;
+    unsigned char B14:1;
+    unsigned char B13:1;
+    unsigned char B12:1;
+    unsigned char B11:1;
+    unsigned char B10:1;
+    unsigned char B9:1;
+    unsigned char B8:1;
+    unsigned char B7:1;
+    unsigned char B6:1;
+    unsigned char B5:1;
+    unsigned char B4:1;
+    unsigned char B3:1;
+    unsigned char B2:1;
+    unsigned char B1:1;
+    unsigned char B0:1;
+  }
+  BIT;
+}
+PADDR;
+
+int
+main ()
+{
+  PADDR.BIT.B0 = 1;
+  PADDR.BIT.B3 = 1;
+  PADDR.BIT.B6 = 1;
+
+  PADDR.BIT.B1 |= 1;
+  PADDR.BIT.B4 |= 1;
+  PADDR.BIT.B7 |= 1;
+
+  PADDR.BIT.B10 = 1;
+  PADDR.BIT.B13 = 1;
+  PADDR.BIT.B15 = 1;
+
+  PADDR.BIT.B9  |= 1;
+  PADDR.BIT.B12 |= 1;
+  PADDR.BIT.B14 |= 1;
+
+  return 0;
+}
+
--- /gcc/testsuite/gcc.target/sh/sh2a-bxor.c	1970-01-01 05:30:00.000000000 +0530
+++ /gcc/testsuite/gcc.target/sh/sh2a-bxor.c	2008-04-04 16:34:43.000000000 +0530
@@ -0,0 +1,92 @@
+/* Testcase to check generation of a SH2A specific instruction for
+   "BXOR.B #imm3, @(disp12, Rn)".  */
+/* { dg-do assemble {target sh*-*-*}}  */
+/* { dg-options "-O1 -mbitops" }  */
+/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single -m2a-single-only" }  */
+/* { dg-final { scan-assembler "bxor.b"} }  */
+
+volatile struct
+{
+  union
+  {
+    unsigned char BYTE;
+    struct
+    {
+      unsigned char BIT7:1;
+      unsigned char BIT6:1;
+      unsigned char BIT5:1;
+      unsigned char BIT4:1;
+      unsigned char BIT3:1;
+      unsigned char BIT2:1;
+      unsigned char BIT1:1;
+      unsigned char BIT0:1;
+    }
+    BIT;
+  }
+  ICR0;
+}
+USRSTR;
+
+volatile union t_IOR
+{
+  unsigned short WORD;
+  struct
+  {
+    unsigned char IOR15:1;
+    unsigned char IOR14:1;
+    unsigned char IOR13:1;
+    unsigned char IOR12:1;
+    unsigned char IOR11:1;
+    unsigned char IOR10:1;
+    unsigned char IOR9:1;
+    unsigned char IOR8:1;
+    unsigned char IOR7:1;
+    unsigned char IOR6:1;
+    unsigned char IOR5:1;
+    unsigned char IOR4:1;
+    unsigned char IOR3:1;
+    unsigned char IOR2:1;
+    unsigned char IOR1:1;
+    unsigned char IOR0:1;
+  }
+  BIT;
+}
+PORT;
+
+int
+main ()
+{
+  volatile unsigned char a;
+
+  /* Instruction generated is BXOR.B #imm3, @(disp12, Rn)  */
+  USRSTR.ICR0.BIT.BIT3 = USRSTR.ICR0.BIT.BIT4 ^ USRSTR.ICR0.BIT.BIT1;
+  USRSTR.ICR0.BIT.BIT2 = USRSTR.ICR0.BIT.BIT6 ^ USRSTR.ICR0.BIT.BIT6;
+  USRSTR.ICR0.BIT.BIT4 = USRSTR.ICR0.BIT.BIT2 ^ USRSTR.ICR0.BIT.BIT4;
+  USRSTR.ICR0.BIT.BIT6 = USRSTR.ICR0.BIT.BIT1 ^ USRSTR.ICR0.BIT.BIT3;
+
+  a = USRSTR.ICR0.BIT.BIT0 ^ USRSTR.ICR0.BIT.BIT1;
+  a = USRSTR.ICR0.BIT.BIT5 ^ USRSTR.ICR0.BIT.BIT7;
+  a = USRSTR.ICR0.BIT.BIT2 ^ USRSTR.ICR0.BIT.BIT6;
+
+  PORT.BIT.IOR13 = PORT.BIT.IOR0  ^  USRSTR.ICR0.BIT.BIT7;
+  PORT.BIT.IOR15 = PORT.BIT.IOR6  ^  USRSTR.ICR0.BIT.BIT2;
+  PORT.BIT.IOR3  = PORT.BIT.IOR2  ^  USRSTR.ICR0.BIT.BIT5;
+  PORT.BIT.IOR1  = PORT.BIT.IOR13 ^  USRSTR.ICR0.BIT.BIT1;
+
+  PORT.BIT.IOR1  = PORT.BIT.IOR2  ^  USRSTR.ICR0.BIT.BIT1;
+  PORT.BIT.IOR11 = PORT.BIT.IOR9  ^  USRSTR.ICR0.BIT.BIT2;
+  PORT.BIT.IOR8  = PORT.BIT.IOR14 ^  USRSTR.ICR0.BIT.BIT5;
+
+  PORT.BIT.IOR10 ^= USRSTR.ICR0.BIT.BIT1;
+  PORT.BIT.IOR1  ^= USRSTR.ICR0.BIT.BIT2;
+  PORT.BIT.IOR5  ^= USRSTR.ICR0.BIT.BIT5;
+  PORT.BIT.IOR14 ^= USRSTR.ICR0.BIT.BIT4;
+
+  /* Instruction generated on using size optimization option "-Os".  */
+  a = a ^ USRSTR.ICR0.BIT.BIT1;
+  a = a ^ USRSTR.ICR0.BIT.BIT4;
+  a = a ^ USRSTR.ICR0.BIT.BIT0;
+
+  return 0;
+}
+

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH,SH] Add SH2A new instructions 6/6
  2008-04-04 13:16                       ` Naveen H.S.
@ 2008-04-04 13:38                         ` Kaz Kojima
  0 siblings, 0 replies; 14+ messages in thread
From: Kaz Kojima @ 2008-04-04 13:38 UTC (permalink / raw)
  To: naveen.hs; +Cc: gcc-patches, Prafulla.Thakare

"Naveen H.S." <naveen.hs@kpitcummins.com> wrote:
> Please find the revised patch attached "sh2a6.patch".

I'll apply this revised patch.  Thanks for your patience!

Regards,
	kaz

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2008-04-04 13:32 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-10-25 13:53 [PATCH,SH] Add SH2A new instructions 6/6 Naveen H.S.
2007-10-28 10:46 ` Kaz Kojima
2008-04-02 12:10   ` Naveen H.S.
2008-04-02 13:46     ` Kaz Kojima
2008-04-03  6:01       ` Naveen H.S.
2008-04-03  9:13         ` Kaz Kojima
2008-04-03 10:52           ` Naveen H.S.
2008-04-03 11:14             ` Kaz Kojima
2008-04-04  9:38               ` Naveen H.S.
2008-04-04 11:17                 ` Kaz Kojima
2008-04-04 12:16                   ` Naveen H.S.
2008-04-04 12:36                     ` Kaz Kojima
2008-04-04 13:16                       ` Naveen H.S.
2008-04-04 13:38                         ` Kaz Kojima

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).