From: Matthew Fortune Date: Thu, 15 Jan 2015 10:44:57 +0000 (+0000) Subject: Add support for the R6 LSA and DLSA instructions X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=954bdd58817e70b138423906f6a4c9947dbd712a;p=gcc.git Add support for the R6 LSA and DLSA instructions gcc/ * config/mips/mips.c (mips_rtx_costs): Set costs for LSA/DLSA. (mips_print_operand): Support 'y' to print exact log2 in decimal of a const_int. * config/mips/mips.h (ISA_HAS_LSA): New define. (ISA_HAS_DLSA): Likewise. * config/mips/mips.md (lsa): New define_insn. * config/mips/predicates.md (const_immlsa_operand): New predicate. gcc/testsuite/ * gcc.target/mips/lsa.c: New file. * gcc.target/mips/mips64-lsa.c: Likewise. * gcc.target/mips/mulsize-2.c: Require !HAS_LSA. * gcc.target/mips/mulsize-4.c: Likewise. * gcc.target/mips/mulsize-5.c: New file. * gcc.target/mips/mulsize-6.c: Likewise. * gcc.target/mips/mips.exp (mips_option_groups): Support HAS_LSA and !HAS_LSA as ghost options. (mips-dg-options): Require rev 6 for HAS_LSA. Downgrade to rev 5 for !HAS_LSA. From-SVN: r219638 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 388bc84ac72..356422321c4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2015-01-14 Matthew Fortune + + * config/mips/mips.c (mips_rtx_costs): Set costs for LSA/DLSA. + (mips_print_operand): Support 'y' to print exact log2 in decimal + of a const_int. + * config/mips/mips.h (ISA_HAS_LSA): New define. + (ISA_HAS_DLSA): Likewise. + * config/mips/mips.md (lsa): New define_insn. + * config/mips/predicates.md (const_immlsa_operand): New predicate. + 2015-01-15 Martin Liska PR target/64377 diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 327aa290ec2..00801bb3ce8 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -4114,6 +4114,22 @@ mips_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED, return false; } + /* If it's an add + mult (which is equivalent to shift left) and + it's immediate operand satisfies const_immlsa_operand predicate. */ + if (((ISA_HAS_LSA && mode == SImode) + || (ISA_HAS_DLSA && mode == DImode)) + && GET_CODE (XEXP (x, 0)) == MULT) + { + rtx op2 = XEXP (XEXP (x, 0), 1); + if (const_immlsa_operand (op2, mode)) + { + *total = (COSTS_N_INSNS (1) + + set_src_cost (XEXP (XEXP (x, 0), 0), speed) + + set_src_cost (XEXP (x, 1), speed)); + return true; + } + } + /* Double-word operations require three single-word operations and an SLTU. The MIPS16 version then needs to move the result of the SLTU from $24 to a MIPS16 register. */ @@ -8419,6 +8435,7 @@ mips_print_operand_punct_valid_p (unsigned char code) 'x' Print the low 16 bits of CONST_INT OP in hexadecimal format. 'd' Print CONST_INT OP in decimal. 'm' Print one less than CONST_INT OP in decimal. + 'y' Print exact log2 of CONST_INT OP in decimal. 'h' Print the high-part relocation associated with OP, after stripping any outermost HIGH. 'R' Print the low-part relocation associated with OP. @@ -8482,6 +8499,19 @@ mips_print_operand (FILE *file, rtx op, int letter) output_operand_lossage ("invalid use of '%%%c'", letter); break; + case 'y': + if (CONST_INT_P (op)) + { + int val = exact_log2 (INTVAL (op)); + if (val != -1) + fprintf (file, "%d", val); + else + output_operand_lossage ("invalid use of '%%%c'", letter); + } + else + output_operand_lossage ("invalid use of '%%%c'", letter); + break; + case 'h': if (code == HIGH) op = XEXP (op, 0); diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index f6f785393f5..c5ea2401a17 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -181,6 +181,12 @@ struct mips_cpu_info { #define ISA_HAS_DSP_MULT ISA_HAS_DSPR2 #endif +/* ISA has LSA available. */ +#define ISA_HAS_LSA (mips_isa_rev >= 6) + +/* ISA has DLSA available. */ +#define ISA_HAS_DLSA (TARGET_64BIT && mips_isa_rev >= 6) + /* The ISA compression flags that are currently in effect. */ #define TARGET_COMPRESSION (target_flags & (MASK_MIPS16 | MASK_MICROMIPS)) diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index f7f26870266..2fb278650ca 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -5541,6 +5541,16 @@ (set_attr "mode" "SI") (set_attr "extended_mips16" "no,no,yes")]) +(define_insn "lsa" + [(set (match_operand:GPR 0 "register_operand" "=d") + (plus:GPR (mult:GPR (match_operand:GPR 1 "register_operand" "d") + (match_operand 2 "const_immlsa_operand" "")) + (match_operand:GPR 3 "register_operand" "d")))] + "ISA_HAS_LSA" + "lsa\t%0,%1,%3,%y2" + [(set_attr "type" "arith") + (set_attr "mode" "")]) + ;; We need separate DImode MIPS16 patterns because of the irregularity ;; of right shifts. (define_insn "*ashldi3_mips16" diff --git a/gcc/config/mips/predicates.md b/gcc/config/mips/predicates.md index ba5c0e3e81f..fa17ac7ca4b 100644 --- a/gcc/config/mips/predicates.md +++ b/gcc/config/mips/predicates.md @@ -33,6 +33,10 @@ (ior (match_operand 0 "const_arith_operand") (match_operand 0 "register_operand"))) +(define_predicate "const_immlsa_operand" + (and (match_code "const_int") + (match_test "IN_RANGE (exact_log2 (INTVAL (op)), 1, 4)"))) + (define_predicate "const_uimm6_operand" (and (match_code "const_int") (match_test "UIMM6_OPERAND (INTVAL (op))"))) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ba1cd3101e4..6b73d3159fb 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,16 @@ +2015-01-14 Matthew Fortune + + * gcc.target/mips/lsa.c: New file. + * gcc.target/mips/mips64-lsa.c: Likewise. + * gcc.target/mips/mulsize-2.c: Require !HAS_LSA. + * gcc.target/mips/mulsize-4.c: Likewise. + * gcc.target/mips/mulsize-5.c: New file. + * gcc.target/mips/mulsize-6.c: Likewise. + * gcc.target/mips/mips.exp (mips_option_groups): Support HAS_LSA + and !HAS_LSA as ghost options. + (mips-dg-options): Require rev 6 for HAS_LSA. Downgrade to rev 5 + for !HAS_LSA. + 2015-01-15 Matthew Wahab * g++.dg/torture/20141013.c: Set -fno-short-enums. diff --git a/gcc/testsuite/gcc.target/mips/lsa.c b/gcc/testsuite/gcc.target/mips/lsa.c new file mode 100644 index 00000000000..d7be17409a3 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/lsa.c @@ -0,0 +1,11 @@ +/* Test MIPS32R6 LSA instruction */ +/* { dg-do compile } */ +/* { dg-options "-mgp32 (HAS_LSA)" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +/* { dg-final { scan-assembler "\tlsa\t" } } */ + +NOMIPS16 signed short test (signed short *a, int index) +{ + return a[index]; +} diff --git a/gcc/testsuite/gcc.target/mips/mips.exp b/gcc/testsuite/gcc.target/mips/mips.exp index 4247cc9f8da..3d6da815c49 100644 --- a/gcc/testsuite/gcc.target/mips/mips.exp +++ b/gcc/testsuite/gcc.target/mips/mips.exp @@ -253,6 +253,7 @@ set mips_option_groups { movn "HAS_MOVN" madd "HAS_MADD" maddps "HAS_MADDPS" + lsa "(|!)HAS_LSA" } for { set option 0 } { $option < 32 } { incr option } { @@ -1061,11 +1062,21 @@ proc mips-dg-options { args } { # Handle dependencies between the pre-arch options and the arch option. # This should mirror the arch and post-arch code below. if { !$arch_test_option_p } { + # We need a revision 6 or better ISA for: + # + # - When the LSA instruction is required + if { $isa_rev < 6 + && ([mips_have_test_option_p options "HAS_LSA"]) } { + if { $gp_size == 32 } { + mips_make_test_option options "-mips32r6" + } else { + mips_make_test_option options "-mips64r6" + } # We need a revision 2 or better ISA for: # # - the combination of -mgp32 -mfp64 # - the DSP ASE - if { $isa_rev < 2 + } elseif { $isa_rev < 2 && (($gp_size == 32 && [mips_have_test_option_p options "-mfp64"]) || [mips_have_test_option_p options "-msynci"] || [mips_have_test_option_p options "-mdsp"] @@ -1142,7 +1153,8 @@ proc mips-dg-options { args } { || [mips_have_test_option_p options "HAS_MADD"] || [mips_have_test_option_p options "-mpaired-single"] || [mips_have_test_option_p options "-mnan=legacy"] - || [mips_have_test_option_p options "-mabs=legacy"]) } { + || [mips_have_test_option_p options "-mabs=legacy"] + || [mips_have_test_option_p options "!HAS_LSA"]) } { if { $gp_size == 32 } { mips_make_test_option options "-mips32r5" } else { diff --git a/gcc/testsuite/gcc.target/mips/mips64-lsa.c b/gcc/testsuite/gcc.target/mips/mips64-lsa.c new file mode 100644 index 00000000000..940847efc55 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/mips64-lsa.c @@ -0,0 +1,11 @@ +/* Test MIPS64R6 LSA instruction */ +/* { dg-do compile } */ +/* { dg-options "-mabi=64 (HAS_LSA)" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +/* { dg-final { scan-assembler "\tdlsa\t" } } */ + +NOMIPS16 signed long long test (signed long long *a, int index) +{ + return a[index]; +} diff --git a/gcc/testsuite/gcc.target/mips/mulsize-2.c b/gcc/testsuite/gcc.target/mips/mulsize-2.c index 4cc2224dff9..7c84bfd9cdd 100644 --- a/gcc/testsuite/gcc.target/mips/mulsize-2.c +++ b/gcc/testsuite/gcc.target/mips/mulsize-2.c @@ -1,3 +1,4 @@ +/* { dg-options "(!HAS_LSA)" } */ /* { dg-final { scan-assembler "\t.globl\tf9" } } */ /* { dg-final { scan-assembler "\tsll\t" } } */ /* { dg-final { scan-assembler "\taddu\t" } } */ diff --git a/gcc/testsuite/gcc.target/mips/mulsize-4.c b/gcc/testsuite/gcc.target/mips/mulsize-4.c index 7694d2c03dc..f8a94a9588e 100644 --- a/gcc/testsuite/gcc.target/mips/mulsize-4.c +++ b/gcc/testsuite/gcc.target/mips/mulsize-4.c @@ -1,3 +1,4 @@ +/* { dg-options "(!HAS_LSA)" } */ /* { dg-final { scan-assembler "\t.globl\tf17" } } */ /* { dg-final { scan-assembler "\tsll\t" } } */ /* { dg-final { scan-assembler "\taddu\t" } } */ diff --git a/gcc/testsuite/gcc.target/mips/mulsize-5.c b/gcc/testsuite/gcc.target/mips/mulsize-5.c new file mode 100644 index 00000000000..1c39a7e3f91 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/mulsize-5.c @@ -0,0 +1,13 @@ +/* { dg-options "(HAS_LSA)" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ +/* { dg-final { scan-assembler "\t.globl\tf9" } } */ +/* { dg-final { scan-assembler "\tlsa\t" } } */ +/* { dg-final { scan-assembler-not "\tsll\t" } } */ +/* { dg-final { scan-assembler-not "\taddu\t" } } */ +/* { dg-final { scan-assembler-not "\tli\t" } } */ +/* { dg-final { scan-assembler-not "\tmul\t" } } */ +int +f9(int x) +{ + return x * 9; +} diff --git a/gcc/testsuite/gcc.target/mips/mulsize-6.c b/gcc/testsuite/gcc.target/mips/mulsize-6.c new file mode 100644 index 00000000000..6e9ca003fc7 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/mulsize-6.c @@ -0,0 +1,13 @@ +/* { dg-options "(HAS_LSA)" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ +/* { dg-final { scan-assembler "\t.globl\tf17" } } */ +/* { dg-final { scan-assembler "\tlsa\t" } } */ +/* { dg-final { scan-assembler-not "\tsll\t" } } */ +/* { dg-final { scan-assembler-not "\taddu\t" } } */ +/* { dg-final { scan-assembler-not "\tli\t" } } */ +/* { dg-final { scan-assembler-not "\tmul\t" } } */ +int +f17(int x) +{ + return x * 17; +}