This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH,MIPS] Add support for the R6 LSA and DLSA instructions


This patch adds support for the R6 [D]LSA instructions.  The support
has been structured to allow MSA (when implemented) to turn on the
same instructions as they are also added by the MSA ASE.

I have continued to use the idea of 'ghost' options in the testsuite to
indicate what features are required rather than arch revisions.

Thanks,
Matthew

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.
---
 gcc/config/mips/mips.c                     | 30 ++++++++++++++++++++++++++++++
 gcc/config/mips/mips.h                     |  6 ++++++
 gcc/config/mips/mips.md                    | 10 ++++++++++
 gcc/config/mips/predicates.md              |  4 ++++
 gcc/testsuite/gcc.target/mips/lsa.c        | 11 +++++++++++
 gcc/testsuite/gcc.target/mips/mips.exp     | 16 ++++++++++++++--
 gcc/testsuite/gcc.target/mips/mips64-lsa.c | 11 +++++++++++
 gcc/testsuite/gcc.target/mips/mulsize-2.c  |  1 +
 gcc/testsuite/gcc.target/mips/mulsize-4.c  |  1 +
 gcc/testsuite/gcc.target/mips/mulsize-5.c  | 13 +++++++++++++
 gcc/testsuite/gcc.target/mips/mulsize-6.c  | 13 +++++++++++++
 11 files changed, 114 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/mips/lsa.c
 create mode 100644 gcc/testsuite/gcc.target/mips/mips64-lsa.c
 create mode 100644 gcc/testsuite/gcc.target/mips/mulsize-5.c
 create mode 100644 gcc/testsuite/gcc.target/mips/mulsize-6.c

diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index c2cc76e..a858a84 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -4108,6 +4108,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.  */
@@ -8413,6 +8429,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.
@@ -8476,6 +8493,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 3d95a58..37d4cb4 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 f7f2687..2fb2786 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -5541,6 +5541,16 @@ (define_insn "*<optab>si3_mips16"
    (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 ba5c0e3..fa17ac7 100644
--- a/gcc/config/mips/predicates.md
+++ b/gcc/config/mips/predicates.md
@@ -33,6 +33,10 @@ (define_predicate "arith_operand"
   (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/gcc.target/mips/lsa.c b/gcc/testsuite/gcc.target/mips/lsa.c
new file mode 100644
index 0000000..d7be174
--- /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 4247cc9..3d6da81 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 0000000..940847e
--- /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 4cc2224..7c84bfd 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 7694d2c..f8a94a9 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 0000000..1c39a7e
--- /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 0000000..6e9ca00
--- /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;
+}
-- 
2.2.1


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]