Commit 954bdd58 by Matthew Fortune Committed by Matthew Fortune

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.

From-SVN: r219638
parent 953bcfa6
2015-01-14 Matthew Fortune <matthew.fortune@imgtec.com>
* 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.
2015-01-15 Martin Liska <mliska@suse.cz> 2015-01-15 Martin Liska <mliska@suse.cz>
PR target/64377 PR target/64377
......
...@@ -4114,6 +4114,22 @@ mips_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED, ...@@ -4114,6 +4114,22 @@ mips_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
return false; 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 /* Double-word operations require three single-word operations and
an SLTU. The MIPS16 version then needs to move the result of an SLTU. The MIPS16 version then needs to move the result of
the SLTU from $24 to a MIPS16 register. */ the SLTU from $24 to a MIPS16 register. */
...@@ -8419,6 +8435,7 @@ mips_print_operand_punct_valid_p (unsigned char code) ...@@ -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. 'x' Print the low 16 bits of CONST_INT OP in hexadecimal format.
'd' Print CONST_INT OP in decimal. 'd' Print CONST_INT OP in decimal.
'm' Print one less than 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 'h' Print the high-part relocation associated with OP, after stripping
any outermost HIGH. any outermost HIGH.
'R' Print the low-part relocation associated with OP. 'R' Print the low-part relocation associated with OP.
...@@ -8482,6 +8499,19 @@ mips_print_operand (FILE *file, rtx op, int letter) ...@@ -8482,6 +8499,19 @@ mips_print_operand (FILE *file, rtx op, int letter)
output_operand_lossage ("invalid use of '%%%c'", letter); output_operand_lossage ("invalid use of '%%%c'", letter);
break; 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': case 'h':
if (code == HIGH) if (code == HIGH)
op = XEXP (op, 0); op = XEXP (op, 0);
......
...@@ -181,6 +181,12 @@ struct mips_cpu_info { ...@@ -181,6 +181,12 @@ struct mips_cpu_info {
#define ISA_HAS_DSP_MULT ISA_HAS_DSPR2 #define ISA_HAS_DSP_MULT ISA_HAS_DSPR2
#endif #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. */ /* The ISA compression flags that are currently in effect. */
#define TARGET_COMPRESSION (target_flags & (MASK_MIPS16 | MASK_MICROMIPS)) #define TARGET_COMPRESSION (target_flags & (MASK_MIPS16 | MASK_MICROMIPS))
......
...@@ -5541,6 +5541,16 @@ ...@@ -5541,6 +5541,16 @@
(set_attr "mode" "SI") (set_attr "mode" "SI")
(set_attr "extended_mips16" "no,no,yes")]) (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 ;; We need separate DImode MIPS16 patterns because of the irregularity
;; of right shifts. ;; of right shifts.
(define_insn "*ashldi3_mips16" (define_insn "*ashldi3_mips16"
......
...@@ -33,6 +33,10 @@ ...@@ -33,6 +33,10 @@
(ior (match_operand 0 "const_arith_operand") (ior (match_operand 0 "const_arith_operand")
(match_operand 0 "register_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" (define_predicate "const_uimm6_operand"
(and (match_code "const_int") (and (match_code "const_int")
(match_test "UIMM6_OPERAND (INTVAL (op))"))) (match_test "UIMM6_OPERAND (INTVAL (op))")))
......
2015-01-14 Matthew Fortune <matthew.fortune@imgtec.com>
* 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 <matthew.wahab@arm.com> 2015-01-15 Matthew Wahab <matthew.wahab@arm.com>
* g++.dg/torture/20141013.c: Set -fno-short-enums. * g++.dg/torture/20141013.c: Set -fno-short-enums.
......
/* 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];
}
...@@ -253,6 +253,7 @@ set mips_option_groups { ...@@ -253,6 +253,7 @@ set mips_option_groups {
movn "HAS_MOVN" movn "HAS_MOVN"
madd "HAS_MADD" madd "HAS_MADD"
maddps "HAS_MADDPS" maddps "HAS_MADDPS"
lsa "(|!)HAS_LSA"
} }
for { set option 0 } { $option < 32 } { incr option } { for { set option 0 } { $option < 32 } { incr option } {
...@@ -1061,11 +1062,21 @@ proc mips-dg-options { args } { ...@@ -1061,11 +1062,21 @@ proc mips-dg-options { args } {
# Handle dependencies between the pre-arch options and the arch option. # Handle dependencies between the pre-arch options and the arch option.
# This should mirror the arch and post-arch code below. # This should mirror the arch and post-arch code below.
if { !$arch_test_option_p } { 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: # We need a revision 2 or better ISA for:
# #
# - the combination of -mgp32 -mfp64 # - the combination of -mgp32 -mfp64
# - the DSP ASE # - the DSP ASE
if { $isa_rev < 2 } elseif { $isa_rev < 2
&& (($gp_size == 32 && [mips_have_test_option_p options "-mfp64"]) && (($gp_size == 32 && [mips_have_test_option_p options "-mfp64"])
|| [mips_have_test_option_p options "-msynci"] || [mips_have_test_option_p options "-msynci"]
|| [mips_have_test_option_p options "-mdsp"] || [mips_have_test_option_p options "-mdsp"]
...@@ -1142,7 +1153,8 @@ proc mips-dg-options { args } { ...@@ -1142,7 +1153,8 @@ proc mips-dg-options { args } {
|| [mips_have_test_option_p options "HAS_MADD"] || [mips_have_test_option_p options "HAS_MADD"]
|| [mips_have_test_option_p options "-mpaired-single"] || [mips_have_test_option_p options "-mpaired-single"]
|| [mips_have_test_option_p options "-mnan=legacy"] || [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 } { if { $gp_size == 32 } {
mips_make_test_option options "-mips32r5" mips_make_test_option options "-mips32r5"
} else { } else {
......
/* 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];
}
/* { dg-options "(!HAS_LSA)" } */
/* { dg-final { scan-assembler "\t.globl\tf9" } } */ /* { dg-final { scan-assembler "\t.globl\tf9" } } */
/* { dg-final { scan-assembler "\tsll\t" } } */ /* { dg-final { scan-assembler "\tsll\t" } } */
/* { dg-final { scan-assembler "\taddu\t" } } */ /* { dg-final { scan-assembler "\taddu\t" } } */
......
/* { dg-options "(!HAS_LSA)" } */
/* { dg-final { scan-assembler "\t.globl\tf17" } } */ /* { dg-final { scan-assembler "\t.globl\tf17" } } */
/* { dg-final { scan-assembler "\tsll\t" } } */ /* { dg-final { scan-assembler "\tsll\t" } } */
/* { dg-final { scan-assembler "\taddu\t" } } */ /* { dg-final { scan-assembler "\taddu\t" } } */
......
/* { 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;
}
/* { 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment