From fbe1d77d63f6224126ff4cdfef439182265b1682 Mon Sep 17 00:00:00 2001
From: Chenghua Xu <paul.hua.gm@gmail.com>
Date: Fri, 31 Aug 2018 11:52:33 +0800
Subject: [PATCH 2/6] [MIPS] Add support for Loongson EXT istructions.

gcc/
	* config/mips/mips.c (mips_option_override): Default enable
	Loongson EXT on Loongson 3a target.
	* config/mips/mips.h (TARGET_CPU_CPP_BUILTINS): Add
	__mips_loongson_ext.
	(ASM_SPEC): Add mloongson-ext and mno-loongson-ext.
	* config/mips/mips.md (mul<mode>3, mul<mode>3_mul3_nohilo,
	<u>div<mode>3, <u>mod<mode>3, prefetch): Use TARGET_LOONGSON_EXT
	instead of TARGET_LOONGSON_3A.
	* config/mips/mips.opt: Add -mloongson-ext option.

gcc/testsuite/
	* gcc.target/mips/mips.exp (mips_option_groups): Add
	-mloongson-ext option.
---
 gcc/config/mips/mips.c                 |    5 +++++
 gcc/config/mips/mips.h                 |    7 +++++++
 gcc/config/mips/mips.md                |   16 ++++++++--------
 gcc/config/mips/mips.opt               |    4 ++++
 gcc/testsuite/gcc.target/mips/mips.exp |    1 +
 5 files changed, 25 insertions(+), 8 deletions(-)

diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index a804f70..019a6dc 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -20178,6 +20178,11 @@ mips_option_override (void)
 	  || (strcmp (mips_arch_info->name, "loongson3a") == 0)))
     target_flags |= MASK_LOONGSON_MMI;
 
+  /* Default to enable Loongson EXT on Longson 3a target.  */
+  if ((target_flags_explicit & MASK_LOONGSON_EXT) == 0
+      && (strcmp (mips_arch_info->name, "loongson3a") == 0))
+    target_flags |= MASK_LOONGSON_EXT;
+
   /* .eh_frame addresses should be the same width as a C pointer.
      Most MIPS ABIs support only one pointer size, so the assembler
      will usually know exactly how big an .eh_frame address is.
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index 3563c1d..e0e78ba 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -596,6 +596,12 @@ struct mips_cpu_info {
 	  builtin_define ("__mips_loongson_mmi");			\
 	}								\
 									\
+      /* Whether Loongson EXT modes are enabled.  */			\
+      if (TARGET_LOONGSON_EXT)						\
+	{								\
+	  builtin_define ("__mips_loongson_ext");			\
+	}								\
+									\
       /* Historical Octeon macro.  */					\
       if (TARGET_OCTEON)						\
 	builtin_define ("__OCTEON__");					\
@@ -1355,6 +1361,7 @@ struct mips_cpu_info {
 %{mginv} %{mno-ginv} \
 %{mmsa} %{mno-msa} \
 %{mloongson-mmi} %{mno-loongson-mmi} \
+%{mloongson-ext} %{mno-loongson-ext} \
 %{msmartmips} %{mno-smartmips} \
 %{mmt} %{mno-mt} \
 %{mfix-rm7000} %{mno-fix-rm7000} \
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index a88c1c5..4b7a627 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -1599,7 +1599,7 @@
 {
   rtx lo;
 
-  if (TARGET_LOONGSON_2EF || TARGET_LOONGSON_3A || ISA_HAS_R6<D>MUL)
+  if (TARGET_LOONGSON_2EF || TARGET_LOONGSON_EXT || ISA_HAS_R6<D>MUL)
     emit_insn (gen_mul<mode>3_mul3_nohilo (operands[0], operands[1],
 					   operands[2]));
   else if (ISA_HAS_<D>MUL3)
@@ -1622,11 +1622,11 @@
   [(set (match_operand:GPR 0 "register_operand" "=d")
         (mult:GPR (match_operand:GPR 1 "register_operand" "d")
                   (match_operand:GPR 2 "register_operand" "d")))]
-  "TARGET_LOONGSON_2EF || TARGET_LOONGSON_3A || ISA_HAS_R6<D>MUL"
+  "TARGET_LOONGSON_2EF || TARGET_LOONGSON_EXT || ISA_HAS_R6<D>MUL"
 {
   if (TARGET_LOONGSON_2EF)
     return "<d>multu.g\t%0,%1,%2";
-  else if (TARGET_LOONGSON_3A)
+  else if (TARGET_LOONGSON_EXT)
     return "gs<d>multu\t%0,%1,%2";
   else
     return "<d>mul\t%0,%1,%2";
@@ -3016,11 +3016,11 @@
   [(set (match_operand:GPR 0 "register_operand" "=&d")
 	(any_div:GPR (match_operand:GPR 1 "register_operand" "d")
 		     (match_operand:GPR 2 "register_operand" "d")))]
-  "TARGET_LOONGSON_2EF || TARGET_LOONGSON_3A || ISA_HAS_R6<D>DIV"
+  "TARGET_LOONGSON_2EF || TARGET_LOONGSON_EXT || ISA_HAS_R6<D>DIV"
   {
     if (TARGET_LOONGSON_2EF)
       return mips_output_division ("<d>div<u>.g\t%0,%1,%2", operands);
-    else if (TARGET_LOONGSON_3A)
+    else if (TARGET_LOONGSON_EXT)
       return mips_output_division ("gs<d>div<u>\t%0,%1,%2", operands);
     else
       return mips_output_division ("<d>div<u>\t%0,%1,%2", operands);
@@ -3032,11 +3032,11 @@
   [(set (match_operand:GPR 0 "register_operand" "=&d")
 	(any_mod:GPR (match_operand:GPR 1 "register_operand" "d")
 		     (match_operand:GPR 2 "register_operand" "d")))]
-  "TARGET_LOONGSON_2EF || TARGET_LOONGSON_3A || ISA_HAS_R6<D>DIV"
+  "TARGET_LOONGSON_2EF || TARGET_LOONGSON_EXT || ISA_HAS_R6<D>DIV"
   {
     if (TARGET_LOONGSON_2EF)
       return mips_output_division ("<d>mod<u>.g\t%0,%1,%2", operands);
-    else if (TARGET_LOONGSON_3A)
+    else if (TARGET_LOONGSON_EXT)
       return mips_output_division ("gs<d>mod<u>\t%0,%1,%2", operands);
     else
       return mips_output_division ("<d>mod<u>\t%0,%1,%2", operands);
@@ -7136,7 +7136,7 @@
 	     (match_operand 2 "const_int_operand" "n"))]
   "ISA_HAS_PREFETCH && TARGET_EXPLICIT_RELOCS"
 {
-  if (TARGET_LOONGSON_2EF || TARGET_LOONGSON_3A)
+  if (TARGET_LOONGSON_2EF || TARGET_LOONGSON_EXT)
     {
       /* Loongson 2[ef] and Loongson 3a use load to $0 for prefetching.  */
       if (TARGET_64BIT)
diff --git a/gcc/config/mips/mips.opt b/gcc/config/mips/mips.opt
index 6767c47..a8fe8db 100644
--- a/gcc/config/mips/mips.opt
+++ b/gcc/config/mips/mips.opt
@@ -463,3 +463,7 @@ Enum(mips_cb_setting) String(always) Value(MIPS_CB_ALWAYS)
 mloongson-mmi
 Target Report Mask(LOONGSON_MMI)
 Use Loongson MultiMedia extensions Instructions (MMI) instructions.
+
+mloongson-ext
+Target Report Mask(LOONGSON_EXT)
+Use Loongson EXTension (EXT) instructions.
diff --git a/gcc/testsuite/gcc.target/mips/mips.exp b/gcc/testsuite/gcc.target/mips/mips.exp
index 4045c59..70f7a99 100644
--- a/gcc/testsuite/gcc.target/mips/mips.exp
+++ b/gcc/testsuite/gcc.target/mips/mips.exp
@@ -297,6 +297,7 @@ foreach option {
     odd-spreg
     msa
     loongson-mmi
+    loongson-ext
 } {
     lappend mips_option_groups $option "-m(no-|)$option"
 }
-- 
1.7.1

