diff -upr /home/naveenh/tars/gcc-4.4-20080222/gcc/config/sh/constraints.md m32c/src/gcc-4.4-20080222/gcc/config/sh/constraints.md --- /home/naveenh/tars/gcc-4.4-20080222/gcc/config/sh/constraints.md 2008-03-24 12:53:02.000000000 +0530 +++ m32c/src/gcc-4.4-20080222/gcc/config/sh/constraints.md 2008-03-20 09:59:58.000000000 +0530 @@ -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))") Only in m32c/src/gcc-4.4-20080222/gcc/config/sh/: constraints.md.orig Only in m32c/src/gcc-4.4-20080222/gcc/config/sh/: predicates.md.orig diff -upr /home/naveenh/tars/gcc-4.4-20080222/gcc/config/sh/sh.c m32c/src/gcc-4.4-20080222/gcc/config/sh/sh.c --- /home/naveenh/tars/gcc-4.4-20080222/gcc/config/sh/sh.c 2008-03-24 12:55:24.000000000 +0530 +++ m32c/src/gcc-4.4-20080222/gcc/config/sh/sh.c 2008-03-20 09:59:59.000000000 +0530 @@ -678,6 +678,8 @@ print_operand_address (FILE *stream, rtx '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. */ @@ -884,6 +886,22 @@ print_operand (FILE *stream, rtx x, int } 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 -upr /home/naveenh/tars/gcc-4.4-20080222/gcc/config/sh/sh.c.orig m32c/src/gcc-4.4-20080222/gcc/config/sh/sh.c.orig --- /home/naveenh/tars/gcc-4.4-20080222/gcc/config/sh/sh.c.orig 2008-03-24 12:53:02.000000000 +0530 +++ m32c/src/gcc-4.4-20080222/gcc/config/sh/sh.c.orig 2008-03-19 14:35:55.000000000 +0530 @@ -678,6 +678,11 @@ print_operand_address (FILE *stream, rtx '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. + 'f' output the bit operator. + 'e' output the bitnot operator. + '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. */ @@ -817,6 +822,21 @@ print_operand (FILE *stream, rtx x, int 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)) { @@ -884,6 +904,22 @@ print_operand (FILE *stream, rtx x, int } 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); @@ -10591,6 +10627,9 @@ sh_expand_t_scc (enum rtx_code code, rtx val = INTVAL (sh_compare_op1); if ((code == EQ && val == 1) || (code == NE && val == 0)) emit_insn (gen_movt (result)); + else if (TARGET_SH2A && ((code == EQ && val == 0) + || (code == NE && val == 1))) + emit_insn (gen_movrt (result)); else if ((code == EQ && val == 0) || (code == NE && val == 1)) { emit_insn (gen_rtx_CLOBBER (VOIDmode, result)); Only in m32c/src/gcc-4.4-20080222/gcc/config/sh/: sh.h.orig diff -upr /home/naveenh/tars/gcc-4.4-20080222/gcc/config/sh/sh.md m32c/src/gcc-4.4-20080222/gcc/config/sh/sh.md --- /home/naveenh/tars/gcc-4.4-20080222/gcc/config/sh/sh.md 2008-03-24 12:55:24.000000000 +0530 +++ m32c/src/gcc-4.4-20080222/gcc/config/sh/sh.md 2008-03-20 10:00:00.000000000 +0530 @@ -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") Only in m32c/src/gcc-4.4-20080222/gcc/config/sh/: sh.md.orig Only in m32c/src/gcc-4.4-20080222/gcc/config/sh/: sh.opt.orig diff -uprN /home/naveenh/tars/gcc-4.4-20080222/gcc/testsuite/gcc.target/sh/sh2a-bclr.c m32c/src/gcc-4.4-20080222/gcc/testsuite/gcc.target/sh/sh2a-bclr.c --- /home/naveenh/tars/gcc-4.4-20080222/gcc/testsuite/gcc.target/sh/sh2a-bclr.c 1970-01-01 05:30:00.000000000 +0530 +++ m32c/src/gcc-4.4-20080222/gcc/testsuite/gcc.target/sh/sh2a-bclr.c 2008-03-19 14:35:52.000000000 +0530 @@ -0,0 +1,59 @@ +/* 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 -uprN /home/naveenh/tars/gcc-4.4-20080222/gcc/testsuite/gcc.target/sh/sh2a-bset.c m32c/src/gcc-4.4-20080222/gcc/testsuite/gcc.target/sh/sh2a-bset.c --- /home/naveenh/tars/gcc-4.4-20080222/gcc/testsuite/gcc.target/sh/sh2a-bset.c 1970-01-01 05:30:00.000000000 +0530 +++ m32c/src/gcc-4.4-20080222/gcc/testsuite/gcc.target/sh/sh2a-bset.c 2008-03-20 09:58:30.000000000 +0530 @@ -0,0 +1,58 @@ +/* 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; +} +