OSDN Git Service

* doc/invoke.texi: Document -mbitops for SH.
authorkkojima <kkojima@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 4 Apr 2008 23:36:19 +0000 (23:36 +0000)
committerkkojima <kkojima@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 4 Apr 2008 23:36:19 +0000 (23:36 +0000)
* 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.

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

15 files changed:
gcc/ChangeLog
gcc/config/sh/constraints.md
gcc/config/sh/predicates.md
gcc/config/sh/sh.c
gcc/config/sh/sh.h
gcc/config/sh/sh.md
gcc/config/sh/sh.opt
gcc/doc/invoke.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/sh/sh2a-band.c [new file with mode: 0644]
gcc/testsuite/gcc.target/sh/sh2a-bclrmem.c [new file with mode: 0644]
gcc/testsuite/gcc.target/sh/sh2a-bld.c [new file with mode: 0644]
gcc/testsuite/gcc.target/sh/sh2a-bor.c [new file with mode: 0644]
gcc/testsuite/gcc.target/sh/sh2a-bsetmem.c [new file with mode: 0644]
gcc/testsuite/gcc.target/sh/sh2a-bxor.c [new file with mode: 0644]

index 41a4296..a4fe162 100644 (file)
@@ -1,3 +1,23 @@
+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.
+
 2008-04-04  Janis Johnson  <janis187@us.ibm.com>
 
        PR target/35620
index 5844793..2caa1d5 100644 (file)
   (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")
   "@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))")))
index c04235c..ff6a1a2 100644 (file)
     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;
+})
index fe25997..6013c2a 100644 (file)
@@ -683,6 +683,7 @@ print_operand_address (FILE *stream, rtx x)
    '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 code)
          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))
        {
index 7a15479..eb37106 100644 (file)
@@ -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;                 \
       }                                                                        \
index f62b3b9..773c347 100644 (file)
@@ -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.
index bce8a5c..b62530f 100644 (file)
@@ -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
index 36c57c5..5152a15 100644 (file)
@@ -746,7 +746,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
@@ -13910,6 +13910,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}.
index 7b2bbe2..08e3545 100644 (file)
@@ -1,3 +1,12 @@
+2008-04-04  Naveen.H.S  <naveen.hs@kpitcummins.com>
+
+       * 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.
+
 2008-04-04  Janis Johnson  <janis187@us.ibm.com>
 
        * g++.dg/other/anon5.C: Don't depend on line number for error message.
diff --git a/gcc/testsuite/gcc.target/sh/sh2a-band.c b/gcc/testsuite/gcc.target/sh/sh2a-band.c
new file mode 100644 (file)
index 0000000..34862b7
--- /dev/null
@@ -0,0 +1,91 @@
+/* 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;
+}
diff --git a/gcc/testsuite/gcc.target/sh/sh2a-bclrmem.c b/gcc/testsuite/gcc.target/sh/sh2a-bclrmem.c
new file mode 100644 (file)
index 0000000..41cb3bd
--- /dev/null
@@ -0,0 +1,55 @@
+/* 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;
+}
diff --git a/gcc/testsuite/gcc.target/sh/sh2a-bld.c b/gcc/testsuite/gcc.target/sh/sh2a-bld.c
new file mode 100644 (file)
index 0000000..1cf56fe
--- /dev/null
@@ -0,0 +1,43 @@
+/* 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;
+}
diff --git a/gcc/testsuite/gcc.target/sh/sh2a-bor.c b/gcc/testsuite/gcc.target/sh/sh2a-bor.c
new file mode 100644 (file)
index 0000000..c3803c6
--- /dev/null
@@ -0,0 +1,91 @@
+/* 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;
+}
diff --git a/gcc/testsuite/gcc.target/sh/sh2a-bsetmem.c b/gcc/testsuite/gcc.target/sh/sh2a-bsetmem.c
new file mode 100644 (file)
index 0000000..b0ebf08
--- /dev/null
@@ -0,0 +1,55 @@
+/* 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;
+}
diff --git a/gcc/testsuite/gcc.target/sh/sh2a-bxor.c b/gcc/testsuite/gcc.target/sh/sh2a-bxor.c
new file mode 100644 (file)
index 0000000..afe0a5e
--- /dev/null
@@ -0,0 +1,91 @@
+/* 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;
+}