diff options
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/config/sh/constraints.md | 26 | ||||
-rw-r--r-- | gcc/config/sh/sh.c | 18 | ||||
-rw-r--r-- | gcc/config/sh/sh.md | 16 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/sh/sh2a-bclr.c | 57 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/sh/sh2a-bset.c | 57 |
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; +} |