diff options
author | mpf <mpf@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-01-15 10:44:57 +0000 |
---|---|---|
committer | mpf <mpf@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-01-15 10:44:57 +0000 |
commit | 79c790699e9bdfc47d19f5aaf3be708b1e96fba1 (patch) | |
tree | eed15a79d06347bc2b53bfc3bde78a728e3c6f3f /gcc/config/mips | |
parent | f43c2381578bc8dd7e463a064fccdc8b46c7901e (diff) |
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 (<GPR:d>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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@219638 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/mips')
-rw-r--r-- | gcc/config/mips/mips.c | 30 | ||||
-rw-r--r-- | gcc/config/mips/mips.h | 6 | ||||
-rw-r--r-- | gcc/config/mips/mips.md | 10 | ||||
-rw-r--r-- | gcc/config/mips/predicates.md | 4 |
4 files changed, 50 insertions, 0 deletions
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 "<GPR:d>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_<GPR:D>LSA" + "<GPR:d>lsa\t%0,%1,%3,%y2" + [(set_attr "type" "arith") + (set_attr "mode" "<GPR: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))"))) |