aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNaveen.H.S <naveen.hs@kpitcummins.com>2008-04-04 23:36:19 +0000
committerKaz Kojima <kkojima@gcc.gnu.org>2008-04-04 23:36:19 +0000
commit9eb3a0dd852a6a0de2c4849391024e7efc70922d (patch)
tree3cdfd635d78201d5b94a867241c320785815e499
parent97db009ce95362bc9c82a73557b79e64efbd0d1d (diff)
downloadgcc-9eb3a0dd852a6a0de2c4849391024e7efc70922d.zip
gcc-9eb3a0dd852a6a0de2c4849391024e7efc70922d.tar.gz
gcc-9eb3a0dd852a6a0de2c4849391024e7efc70922d.tar.bz2
invoke.texi: Document -mbitops for SH.
* 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. From-SVN: r133919
-rw-r--r--gcc/ChangeLog20
-rw-r--r--gcc/config/sh/constraints.md22
-rw-r--r--gcc/config/sh/predicates.md16
-rw-r--r--gcc/config/sh/sh.c16
-rw-r--r--gcc/config/sh/sh.h6
-rw-r--r--gcc/config/sh/sh.md312
-rw-r--r--gcc/config/sh/sh.opt4
-rw-r--r--gcc/doc/invoke.texi6
-rw-r--r--gcc/testsuite/ChangeLog9
-rw-r--r--gcc/testsuite/gcc.target/sh/sh2a-band.c91
-rw-r--r--gcc/testsuite/gcc.target/sh/sh2a-bclrmem.c55
-rw-r--r--gcc/testsuite/gcc.target/sh/sh2a-bld.c43
-rw-r--r--gcc/testsuite/gcc.target/sh/sh2a-bor.c91
-rw-r--r--gcc/testsuite/gcc.target/sh/sh2a-bsetmem.c55
-rw-r--r--gcc/testsuite/gcc.target/sh/sh2a-bxor.c91
15 files changed, 830 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 41a4296..a4fe162 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/sh/constraints.md b/gcc/config/sh/constraints.md
index 5844793..2caa1d5 100644
--- a/gcc/config/sh/constraints.md
+++ b/gcc/config/sh/constraints.md
@@ -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))")))
diff --git a/gcc/config/sh/predicates.md b/gcc/config/sh/predicates.md
index c04235c..ff6a1a28 100644
--- a/gcc/config/sh/predicates.md
+++ b/gcc/config/sh/predicates.md
@@ -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;
+})
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index fe25997..6013c2a 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -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))
{
diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h
index 7a15479..eb37106 100644
--- a/gcc/config/sh/sh.h
+++ b/gcc/config/sh/sh.h
@@ -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; \
} \
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index f62b3b9..773c347 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -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")])
+
;; -------------------------------------------------------------------------
;; 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.
diff --git a/gcc/config/sh/sh.opt b/gcc/config/sh/sh.opt
index bce8a5c..b62530f 100644
--- a/gcc/config/sh/sh.opt
+++ b/gcc/config/sh/sh.opt
@@ -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
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 36c57c5..5152a15 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -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}.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 7b2bbe2..08e3545 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..34862b7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/sh2a-band.c
@@ -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
index 0000000..41cb3bd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/sh2a-bclrmem.c
@@ -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
index 0000000..1cf56fe
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/sh2a-bld.c
@@ -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
index 0000000..c3803c6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/sh2a-bor.c
@@ -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
index 0000000..b0ebf08
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/sh2a-bsetmem.c
@@ -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
index 0000000..afe0a5e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/sh2a-bxor.c
@@ -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;
+}