aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/mips
diff options
context:
space:
mode:
authormpf <mpf@138bc75d-0d04-0410-961f-82ee72b054a4>2015-01-15 10:44:57 +0000
committermpf <mpf@138bc75d-0d04-0410-961f-82ee72b054a4>2015-01-15 10:44:57 +0000
commit79c790699e9bdfc47d19f5aaf3be708b1e96fba1 (patch)
treeeed15a79d06347bc2b53bfc3bde78a728e3c6f3f /gcc/config/mips
parentf43c2381578bc8dd7e463a064fccdc8b46c7901e (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.c30
-rw-r--r--gcc/config/mips/mips.h6
-rw-r--r--gcc/config/mips/mips.md10
-rw-r--r--gcc/config/mips/predicates.md4
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))")))