From c84241327480cec52608beaba811faf1f09e0b03 Mon Sep 17 00:00:00 2001 From: Adam Nemet <anemet@caviumnetworks.com> Date: Thu, 4 Sep 2008 21:24:31 +0000 Subject: [PATCH] mips.h (ISA_HAS_EXTS): New macro. * config/mips/mips.h (ISA_HAS_EXTS): New macro. * config/mips/mips.md (*ashr_trunc<mode>): Name the pattern combining an arithmetic right shift by more than 31 and a trunction. Don't match for out-of-range shift amounts. Set attribute mode to <MODE>. (*lshr32_trunc<mode>): Name the pattern combining a logical right shift by 32 and and a truncation. Set attribute mode to <MODE>. (*<optab>_trunc<mode>_exts): New pattern for truncated right shifts by less than 32. (extv): Change predicate on first operand to accept registers. Change predicate of the other operands from immediate_operand to const_int_operand. Expand exts when source is a register. (extzv): Change predicate of the constant operands from immediate_operand to const_int_operand. (extzv<mode>): Change predicate of the constant operands from immediate_operand to const_int_operand and no constraint. Also remove mode. (*extzv_trunc<mode>_exts): New pattern. testsuite/ * gcc.target/mips/truncate-2.c: New test. * gcc.target/mips/octeon-exts-1.c: New test. * gcc.target/mips/octeon-exts-2.c: New test. * gcc.target/mips/octeon-exts-3.c: New test. * gcc.target/mips/octeon-exts-4.c: New test. From-SVN: r140009 --- gcc/ChangeLog | 21 ++++++ gcc/config/mips/mips.h | 3 + gcc/config/mips/mips.md | 72 +++++++++++++++---- gcc/testsuite/ChangeLog | 8 +++ gcc/testsuite/gcc.target/mips/octeon-exts-1.c | 16 +++++ gcc/testsuite/gcc.target/mips/octeon-exts-2.c | 37 ++++++++++ gcc/testsuite/gcc.target/mips/octeon-exts-3.c | 35 +++++++++ gcc/testsuite/gcc.target/mips/octeon-exts-4.c | 20 ++++++ gcc/testsuite/gcc.target/mips/truncate-2.c | 20 ++++++ 9 files changed, 220 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/gcc.target/mips/octeon-exts-1.c create mode 100644 gcc/testsuite/gcc.target/mips/octeon-exts-2.c create mode 100644 gcc/testsuite/gcc.target/mips/octeon-exts-3.c create mode 100644 gcc/testsuite/gcc.target/mips/octeon-exts-4.c create mode 100644 gcc/testsuite/gcc.target/mips/truncate-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2350a47c9eb4..d035a4bfdff5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,24 @@ +2008-09-04 Adam Nemet <anemet@caviumnetworks.com> + + * config/mips/mips.h (ISA_HAS_EXTS): New macro. + * config/mips/mips.md (*ashr_trunc<mode>): Name the pattern + combining an arithmetic right shift by more than 31 and a + trunction. Don't match for out-of-range shift amounts. Set + attribute mode to <MODE>. + (*lshr32_trunc<mode>): Name the pattern combining a logical right + shift by 32 and and a truncation. Set attribute mode to <MODE>. + (*<optab>_trunc<mode>_exts): New pattern for truncated right + shifts by less than 32. + (extv): Change predicate on first operand to accept registers. + Change predicate of the other operands from immediate_operand to + const_int_operand. Expand exts when source is a register. + (extzv): Change predicate of the constant operands from + immediate_operand to const_int_operand. + (extzv<mode>): Change predicate of the constant operands from + immediate_operand to const_int_operand and no constraint. Also + remove mode. + (*extzv_trunc<mode>_exts): New pattern. + 2008-09-04 Adam Nemet <anemet@caviumnetworks.com> * config/mips/mips.h (ISA_HAS_CINS): New macro. diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index a3f47f79dcfe..46775464470c 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -1012,6 +1012,9 @@ enum mips_code_readable_setting { /* ISA includes the cins instruction. */ #define ISA_HAS_CINS TARGET_OCTEON +/* ISA includes the exts instruction. */ +#define ISA_HAS_EXTS TARGET_OCTEON + /* ISA includes the pop instruction. */ #define ISA_HAS_POP TARGET_OCTEON diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index 04dd30a1e10c..0f478cf558fa 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -772,6 +772,10 @@ ;; to use the same template. (define_code_iterator any_extend [sign_extend zero_extend]) +;; This code iterator allows the two right shift instructions to be +;; generated from the same template. +(define_code_iterator any_shiftrt [ashiftrt lshiftrt]) + ;; This code iterator allows the three shift instructions to be generated ;; from the same template. (define_code_iterator any_shift [ashift ashiftrt lshiftrt]) @@ -2683,17 +2687,17 @@ ;; Combiner patterns to optimize shift/truncate combinations. -(define_insn "" +(define_insn "*ashr_trunc<mode>" [(set (match_operand:SUBDI 0 "register_operand" "=d") (truncate:SUBDI (ashiftrt:DI (match_operand:DI 1 "register_operand" "d") (match_operand:DI 2 "const_arith_operand" ""))))] - "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) >= 32" + "TARGET_64BIT && !TARGET_MIPS16 && IN_RANGE (INTVAL (operands[2]), 32, 63)" "dsra\t%0,%1,%2" [(set_attr "type" "shift") - (set_attr "mode" "SI")]) + (set_attr "mode" "<MODE>")]) -(define_insn "" +(define_insn "*lshr32_trunc<mode>" [(set (match_operand:SUBDI 0 "register_operand" "=d") (truncate:SUBDI (lshiftrt:DI (match_operand:DI 1 "register_operand" "d") @@ -2701,8 +2705,19 @@ "TARGET_64BIT && !TARGET_MIPS16" "dsra\t%0,%1,32" [(set_attr "type" "shift") - (set_attr "mode" "SI")]) + (set_attr "mode" "<MODE>")]) +;; Logical shift by 32 or more results in proper SI values so +;; truncation is removed by the middle end. +(define_insn "*<optab>_trunc<mode>_exts" + [(set (match_operand:SUBDI 0 "register_operand" "=d") + (truncate:SUBDI + (any_shiftrt:DI (match_operand:DI 1 "register_operand" "d") + (match_operand:DI 2 "const_arith_operand" ""))))] + "ISA_HAS_EXTS && TARGET_64BIT && UINTVAL (operands[2]) < 32" + "exts\t%0,%1,%2,31" + [(set_attr "type" "arith") + (set_attr "mode" "<MODE>")]) ;; Combiner patterns for truncate/sign_extend combinations. The SI versions ;; use the shift/truncate patterns above. @@ -3353,24 +3368,46 @@ (define_expand "extv" [(set (match_operand 0 "register_operand") - (sign_extract (match_operand:QI 1 "memory_operand") - (match_operand 2 "immediate_operand") - (match_operand 3 "immediate_operand")))] + (sign_extract (match_operand 1 "nonimmediate_operand") + (match_operand 2 "const_int_operand") + (match_operand 3 "const_int_operand")))] "!TARGET_MIPS16" { if (mips_expand_ext_as_unaligned_load (operands[0], operands[1], INTVAL (operands[2]), INTVAL (operands[3]))) DONE; + else if (register_operand (operands[1], GET_MODE (operands[0])) + && ISA_HAS_EXTS && UINTVAL (operands[2]) <= 32) + { + if (GET_MODE (operands[0]) == DImode) + emit_insn (gen_extvdi (operands[0], operands[1], operands[2], + operands[3])); + else + emit_insn (gen_extvsi (operands[0], operands[1], operands[2], + operands[3])); + DONE; + } else FAIL; }) +(define_insn "extv<mode>" + [(set (match_operand:GPR 0 "register_operand" "=d") + (sign_extract:GPR (match_operand:GPR 1 "register_operand" "d") + (match_operand 2 "const_int_operand" "") + (match_operand 3 "const_int_operand" "")))] + "ISA_HAS_EXTS && UINTVAL (operands[2]) <= 32" + "exts\t%0,%1,%3,%m2" + [(set_attr "type" "arith") + (set_attr "mode" "<MODE>")]) + + (define_expand "extzv" [(set (match_operand 0 "register_operand") (zero_extract (match_operand 1 "nonimmediate_operand") - (match_operand 2 "immediate_operand") - (match_operand 3 "immediate_operand")))] + (match_operand 2 "const_int_operand") + (match_operand 3 "const_int_operand")))] "!TARGET_MIPS16" { if (mips_expand_ext_as_unaligned_load (operands[0], operands[1], @@ -3395,14 +3432,25 @@ (define_insn "extzv<mode>" [(set (match_operand:GPR 0 "register_operand" "=d") (zero_extract:GPR (match_operand:GPR 1 "register_operand" "d") - (match_operand:SI 2 "immediate_operand" "I") - (match_operand:SI 3 "immediate_operand" "I")))] + (match_operand 2 "const_int_operand" "") + (match_operand 3 "const_int_operand" "")))] "mips_use_ins_ext_p (operands[1], INTVAL (operands[2]), INTVAL (operands[3]))" "<d>ext\t%0,%1,%3,%2" [(set_attr "type" "arith") (set_attr "mode" "<MODE>")]) +(define_insn "*extzv_trunc<mode>_exts" + [(set (match_operand:GPR 0 "register_operand" "=d") + (truncate:GPR + (zero_extract:DI (match_operand:DI 1 "register_operand" "d") + (match_operand 2 "const_int_operand" "") + (match_operand 3 "const_int_operand" ""))))] + "ISA_HAS_EXTS && TARGET_64BIT && IN_RANGE (INTVAL (operands[2]), 32, 63)" + "exts\t%0,%1,%3,31" + [(set_attr "type" "arith") + (set_attr "mode" "<MODE>")]) + (define_expand "insv" [(set (zero_extract (match_operand 0 "nonimmediate_operand") diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b6f573e7fc03..9eeb9cc27dc5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2008-09-04 Adam Nemet <anemet@caviumnetworks.com> + + * gcc.target/mips/truncate-2.c: New test. + * gcc.target/mips/octeon-exts-1.c: New test. + * gcc.target/mips/octeon-exts-2.c: New test. + * gcc.target/mips/octeon-exts-3.c: New test. + * gcc.target/mips/octeon-exts-4.c: New test. + 2008-09-04 Adam Nemet <anemet@caviumnetworks.com> * gcc.target/mips/octeon-cins-1.c: New test. diff --git a/gcc/testsuite/gcc.target/mips/octeon-exts-1.c b/gcc/testsuite/gcc.target/mips/octeon-exts-1.c new file mode 100644 index 000000000000..bdaa0b927ef4 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/octeon-exts-1.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-mips-options "-march=octeon" } */ +/* { dg-final { scan-assembler "\texts\t" } } */ + +struct foo +{ + long long a:3; + long long b:23; + long long c:38; +}; + +NOMIPS16 int +f (struct foo s) +{ + return s.b; +} diff --git a/gcc/testsuite/gcc.target/mips/octeon-exts-2.c b/gcc/testsuite/gcc.target/mips/octeon-exts-2.c new file mode 100644 index 000000000000..a87c5fb45db9 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/octeon-exts-2.c @@ -0,0 +1,37 @@ +/* { dg-do compile } */ +/* { dg-mips-options "-O -march=octeon" } */ +/* { dg-final { scan-assembler-times "\texts\t" 4 } } */ + +struct bar +{ + unsigned long long a:1; + long long b:14; + unsigned long long c:48; + long long d:1; +}; + +NOMIPS16 int +f1 (struct bar *s, int a) +{ + return (int) s->b + a; +} + +NOMIPS16 char +f2 (struct bar *s) +{ + return s->d + 1; +} + +NOMIPS16 int +f3 () +{ + struct bar s; + asm ("" : "=r"(s)); + return (int) s.b + 1; +} + +NOMIPS16 long long +f4 (struct bar *s) +{ + return s->d; +} diff --git a/gcc/testsuite/gcc.target/mips/octeon-exts-3.c b/gcc/testsuite/gcc.target/mips/octeon-exts-3.c new file mode 100644 index 000000000000..d7610f82e327 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/octeon-exts-3.c @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-mips-options "-O -march=octeon -mgp64" } */ +/* { dg-final { scan-assembler-times "\texts\t" 3 } } */ + +struct foo +{ + unsigned long long a:10; + unsigned long long b:32; + unsigned long long c:22; +}; + +NOMIPS16 unsigned +f (struct foo s) +{ + return s.b; +} + +struct bar +{ + unsigned long long a:15; + unsigned long long b:48; + unsigned long long c:1; +}; + +NOMIPS16 int +g (struct bar s) +{ + return (int) s.b; +} + +NOMIPS16 int +h (int i) +{ + return (i << 4) >> 24; +} diff --git a/gcc/testsuite/gcc.target/mips/octeon-exts-4.c b/gcc/testsuite/gcc.target/mips/octeon-exts-4.c new file mode 100644 index 000000000000..475fa21e8dcd --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/octeon-exts-4.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-mips-options "-O -march=octeon -mgp64" } */ +/* { dg-final { scan-assembler-not "\tsll\t\[^\n\]*,0" } } */ +/* { dg-final { scan-assembler-times "\texts\t" 6 } } */ + +#define TEST(ID, TYPE, SHIFT) \ + int NOMIPS16 \ + f##ID (long long y) \ + { \ + return (TYPE) ((TYPE) (y >> SHIFT) + 1); \ + } \ + int NOMIPS16 \ + g##ID (unsigned long long y) \ + { \ + return (TYPE) ((TYPE) (y >> SHIFT) + 1); \ + } + +TEST (1, int, 10) +TEST (2, short, 5) +TEST (3, char, 31) diff --git a/gcc/testsuite/gcc.target/mips/truncate-2.c b/gcc/testsuite/gcc.target/mips/truncate-2.c new file mode 100644 index 000000000000..51125a481902 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/truncate-2.c @@ -0,0 +1,20 @@ +/* { dg-mips-options "-O -mgp64" } */ + +#define TEST(ID, TYPE, SHIFT) \ + int NOMIPS16 \ + f##ID (long long y) \ + { \ + return (TYPE) ((TYPE) (y >> SHIFT) + 1); \ + } + +TEST (1, int, 32) +TEST (2, short, 32) +TEST (3, char, 32) +TEST (4, int, 33) +TEST (5, short, 33) +TEST (6, char, 33) +TEST (7, int, 61) +TEST (8, short, 61) +TEST (9, char, 61) + +/* { dg-final { scan-assembler-not "\tsll\t\[^\n\]*,0" } } */ -- GitLab