constraints.md (Pso, Psz): New constraints.
authorNaveen.H.S <naveen.hs@kpitcummins.com>
Tue, 25 Mar 2008 13:44:00 +0000 (13:44 +0000)
committerKaz Kojima <kkojima@gcc.gnu.org>
Tue, 25 Mar 2008 13:44:00 +0000 (13:44 +0000)
* 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.

* gcc.target/sh/sh2a-bclr.c: New test.
* gcc.target/sh/sh2a-bset.c: New test.

From-SVN: r133518

gcc/ChangeLog
gcc/config/sh/constraints.md
gcc/config/sh/sh.c
gcc/config/sh/sh.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/sh/sh2a-bclr.c [new file with mode: 0644]
gcc/testsuite/gcc.target/sh/sh2a-bset.c [new file with mode: 0644]

index 97b2f64c8fe449e050b6e8fb41d7c46ba7877a87..03f6332e777273aeaae5f2965d011763a7abed0c 100644 (file)
@@ -1,3 +1,9 @@
+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
index 7509fae67ee1cfd863d4a9d06551f89f938cc14a..5844793e59edfed7e7ad6804c2d879227177ab38 100644 (file)
@@ -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
    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))")
index 699ac899bffe7599359691f8355849e7a4b4fcbf..8bba3228a7cbf12edb48c4a629031825cd5ba62f 100644 (file)
@@ -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);
 
index 61e902563ef0d828fba30e70a69a8f64eed27217..f62b3b9594af07775a8bb791e9bf234a6069acb1 100644 (file)
@@ -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")
index da9126067ad1716fda90ba8268b4855ed6719aa3..05e9c267e869203e3639d94aa636fe8422befeaf 100644 (file)
@@ -1,3 +1,8 @@
+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.
diff --git a/gcc/testsuite/gcc.target/sh/sh2a-bclr.c b/gcc/testsuite/gcc.target/sh/sh2a-bclr.c
new file mode 100644 (file)
index 0000000..d4e11f9
--- /dev/null
@@ -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 (file)
index 0000000..b64852b
--- /dev/null
@@ -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;
+}