aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/sh/constraints.md26
-rw-r--r--gcc/config/sh/sh.c18
-rw-r--r--gcc/config/sh/sh.md16
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/sh/sh2a-bclr.c57
-rw-r--r--gcc/testsuite/gcc.target/sh/sh2a-bset.c57
7 files changed, 185 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 97b2f64..03f6332 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,11 @@
2008-03-25 Naveen.H.S <naveen.hs@kpitcummins.com>
+ * config/sh/constraints.md (Pso, Psz): New constraints.
+ * config/sh/sh.c (print_operand): Add %V and %W operand codes.
+ * config/sh/sh.md (*andsi3_bclr, *iorsi3_bset): New insns.
+
+2008-03-25 Naveen.H.S <naveen.hs@kpitcummins.com>
+
* config/sh/sh.c (sh_expand_t_scc): Emit movrt for SH2A if
possible.
* config/sh/sh.md (xorsi3_movrt, movrt): New insns.
diff --git a/gcc/config/sh/constraints.md b/gcc/config/sh/constraints.md
index 7509fae..5844793 100644
--- a/gcc/config/sh/constraints.md
+++ b/gcc/config/sh/constraints.md
@@ -35,6 +35,8 @@
;; M: 1
;; N: 0
;; P27: 1 | 2 | 8 | 16
+;; Pso: 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128
+;; Psz: ~1 | ~2 | ~4 | ~8 | ~16 | ~32 | ~64 | ~128
;; Q: pc relative load operand
;; Rxx: reserved for exotic register classes.
;; Sxx: extra memory (storage) constraints
@@ -204,6 +206,30 @@
PIC_DIRECT_ADDR_P."
(match_test "IS_NON_EXPLICIT_CONSTANT_P (op)"))
+(define_constraint "Pso"
+ "Integer constant with a single bit set in its lower 8-bit."
+ (and (match_code "const_int")
+ (ior (match_test "ival == 1")
+ (match_test "ival == 2")
+ (match_test "ival == 4")
+ (match_test "ival == 8")
+ (match_test "ival == 16")
+ (match_test "ival == 32")
+ (match_test "ival == 64")
+ (match_test "ival == 128"))))
+
+(define_constraint "Psz"
+ "Integer constant with a single zero bit in the lower 8-bit."
+ (and (match_code "const_int")
+ (ior (match_test "~ival == 1")
+ (match_test "~ival == 2")
+ (match_test "~ival == 4")
+ (match_test "~ival == 8")
+ (match_test "~ival == 16")
+ (match_test "~ival == 32")
+ (match_test "~ival == 64")
+ (match_test "~ival == 128"))))
+
(define_memory_constraint "Sr0"
"@internal"
(and (match_test "memory_operand (op, GET_MODE (op))")
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 699ac89..8bba322 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -681,6 +681,8 @@ print_operand_address (FILE *stream, rtx x)
'd' print a V2SF reg as dN instead of fpN.
'm' print a pair `base,offset' or `base,index', for LD and ST.
'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.
'u' prints the lowest 16 bits of CONST_INT, as an unsigned value.
'o' output an operator. */
@@ -887,6 +889,22 @@ print_operand (FILE *stream, rtx x, int code)
}
break;
+ case 'V':
+ {
+ int num = exact_log2 (INTVAL (x));
+ gcc_assert (num >= 0);
+ fprintf (stream, "#%d", num);
+ }
+ break;
+
+ case 'W':
+ {
+ int num = exact_log2 (~INTVAL (x));
+ gcc_assert (num >= 0);
+ fprintf (stream, "#%d", num);
+ }
+ break;
+
case 'd':
gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == V2SFmode);
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index 61e9025..f62b3b9 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -3170,6 +3170,14 @@ label:
andi %1, %2, %0"
[(set_attr "type" "arith_media")])
+(define_insn "*andsi3_bclr"
+ [(set (match_operand:SI 0 "arith_reg_dest" "=r")
+ (and:SI (match_operand:SI 1 "arith_reg_operand" "%0")
+ (match_operand:SI 2 "const_int_operand" "Psz")))]
+ "TARGET_SH2A && satisfies_constraint_Psz (operands[2])"
+ "bclr\\t%W2,%0"
+ [(set_attr "type" "arith")])
+
;; If the constant is 255, then emit an extu.b instruction instead of an
;; and, since that will give better code.
@@ -3252,6 +3260,14 @@ 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")
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index da91260..05e9c26 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,10 @@
2008-03-25 Naveen.H.S <naveen.hs@kpitcummins.com>
+ * gcc.target/sh/sh2a-bclr.c: New test.
+ * gcc.target/sh/sh2a-bset.c: New test.
+
+2008-03-25 Naveen.H.S <naveen.hs@kpitcummins.com>
+
* gcc.target/sh/sh2a-movrt.c: New test.
2008-03-25 Naveen.H.S <naveen.hs@kpitcummins.com>
diff --git a/gcc/testsuite/gcc.target/sh/sh2a-bclr.c b/gcc/testsuite/gcc.target/sh/sh2a-bclr.c
new file mode 100644
index 0000000..d4e11f9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/sh2a-bclr.c
@@ -0,0 +1,57 @@
+/* Testcase to check generation of a SH2A specific instruction
+ 'BCLR #imm3,Rn'. */
+/* { 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"} } */
+
+struct a
+{
+ char a, b;
+ short c;
+};
+
+/* This function generates the instruction "BCLR #imm3,Rn" only
+ on using optimization option "-O1" and above. */
+
+int
+a2 ()
+{
+ volatile int j;
+ volatile static struct a x = {1, 66, ~1}, y = {1, 2, ~2};
+
+ if (j > 1)
+ return (x.a == y.a && (x.b & ~1) == y.b);
+ if (j > 2)
+ return (x.a == y.a && (x.b & ~2) == y.b);
+ if (j > 3)
+ return (x.a == y.a && (x.b & ~4) == y.b);
+ if (j > 4)
+ return (x.a == y.a && (x.b & ~8) == y.b);
+ if (j > 5)
+ return (x.a == y.a && (x.b & ~16) == y.b);
+ if (j > 6)
+ return (x.a == y.a && (x.b & ~32) == y.b);
+ if (j > 7)
+ return (x.a == y.a && (x.b & ~64) == y.b);
+ if (j > 8)
+ return (x.a == y.a && (x.b & ~128) == y.b);
+}
+
+int
+main ()
+{
+ volatile unsigned char x;
+
+ x &= 0xFE;
+ x &= 0xFD;
+ x &= 0xFB;
+ x &= 0xF7;
+ x &= 0xEF;
+ x &= 0xDF;
+ x &= 0xBF;
+ x &= 0x7F;
+
+ if (!a2 ())
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/sh/sh2a-bset.c b/gcc/testsuite/gcc.target/sh/sh2a-bset.c
new file mode 100644
index 0000000..b64852b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/sh2a-bset.c
@@ -0,0 +1,57 @@
+/* Testcase to check generation of a SH2A specific instruction
+ 'BSET #imm3,Rn'. */
+/* { dg-do assemble {target sh*-*-*}} */
+/* { dg-options "-O1" } */
+/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single -m2a-single-only" } */
+/* { dg-final { scan-assembler "bset"} } */
+
+struct a
+{
+ char a, b;
+ short c;
+};
+
+/* This function generates the instruction "BSET #imm3,Rn" only
+ on using optimization option "-O1" and above. */
+
+int
+a2 ()
+{
+ volatile int j;
+ volatile static struct a x = {1, 66, ~1}, y = {1, 2, ~2};
+
+ if (j > 1)
+ return (x.a == y.a && (x.b | 1) == y.b);
+ if (j > 2)
+ return (x.a == y.a && (x.b | 2) == y.b);
+ if (j > 3)
+ return (x.a == y.a && (x.b | 4) == y.b);
+ if (j > 4)
+ return (x.a == y.a && (x.b | 8) == y.b);
+ if (j > 5)
+ return (x.a == y.a && (x.b | 16) == y.b);
+ if (j > 6)
+ return (x.a == y.a && (x.b | 32) == y.b);
+ if (j > 7)
+ return (x.a == y.a && (x.b | 64) == y.b);
+ if (j > 8)
+ return (x.a == y.a && (x.b | 128) == y.b);
+}
+
+int
+main ()
+{
+ volatile unsigned char x;
+
+ x |= 0x1;
+ x |= 0x2;
+ x |= 0x4;
+ x |= 0x8;
+ x |= 0x16;
+ x |= 0x32;
+ x |= 0x64;
+ x |= 0x128;
+
+ if (!a2 ())
+ return 0;
+}