From 0df9c46bea628086ca2c4b5db24c28cec912d319 Mon Sep 17 00:00:00 2001
From: Chenghua Xu <paul.hua.gm@gmail.com>
Date: Mon, 3 Sep 2018 20:01:54 +0800
Subject: [PATCH 6/6] Add support for Loongson 2K1000 proccessor.

gcc/
	* config/mips/gs264e.md: New.
	* config/mips/mips-cpus.def: Define gs264e.
	* config/mips/mips-tables.opt: Regenerate.
	* config/mips/mips.c (mips_rtx_cost_data): Add DEFAULT_COSTS for
	gs264e.
	(mips_issue_rate): Add support for gs264e.
	(mips_multipass_dfa_lookahead): Likewise.
	(mips_option_override): Enable MMI, EXT, EXT2 and MSA for gs264e.
	* config/mips/mips.h: Define TARGET_GS264E and TUNE_GS264E.
	(MIPS_ISA_LEVEL_SPEC): Infer mips64r2 from gs264e.
	(ISA_HAS_FUSED_MADD4): Enable for TARGET_GS264E.
	(ISA_HAS_UNFUSED_MADD4): Exclude TARGET_GS264E.
	* config/mips/mips.md: Include gs264e.md.
	(processor): Add gs264e.
	* config/mips/mips.opt (MSA): Use Mask instead of Var.
	* doc/invoke.texi: Add gs264e to supported architectures.
---
 gcc/config/mips/gs264e.md       | 133 ++++++++++++++++++++++++++++++++++++++++
 gcc/config/mips/mips-cpus.def   |   1 +
 gcc/config/mips/mips-tables.opt |  19 +++---
 gcc/config/mips/mips.c          |  29 ++++++---
 gcc/config/mips/mips.h          |  12 ++--
 gcc/config/mips/mips.md         |   2 +
 gcc/config/mips/mips.opt        |   2 +-
 gcc/doc/invoke.texi             |   1 +
 8 files changed, 178 insertions(+), 21 deletions(-)
 create mode 100644 gcc/config/mips/gs264e.md

diff --git a/gcc/config/mips/gs264e.md b/gcc/config/mips/gs264e.md
new file mode 100644
index 00000000000..8f1f9e17e08
--- /dev/null
+++ b/gcc/config/mips/gs264e.md
@@ -0,0 +1,133 @@
+;; Pipeline model for Loongson gs264e cores.
+
+;; Copyright (C) 2018 Free Software Foundation, Inc.
+;;
+;; This file is part of GCC.
+;;
+;; GCC is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published
+;; by the Free Software Foundation; either version 3, or (at your
+;; option) any later version.
+;;
+;; GCC is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+;; License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GCC; see the file COPYING3.  If not see
+;; <http://www.gnu.org/licenses/>.
+
+;; Uncomment the following line to output automata for debugging.
+;; (automata_option "v")
+
+;; Automaton for integer instructions.
+(define_automaton "gs264e_a_alu")
+
+;; Automaton for floating-point instructions.
+(define_automaton "gs264e_a_falu")
+
+;; Automaton for memory operations.
+(define_automaton "gs264e_a_mem")
+
+;; Describe the resources.
+
+(define_cpu_unit "gs264e_alu1" "gs264e_a_alu")
+(define_cpu_unit "gs264e_mem1" "gs264e_a_mem")
+(define_cpu_unit "gs264e_falu1" "gs264e_a_falu")
+
+;; Describe instruction reservations.
+
+(define_insn_reservation "gs264e_arith" 1
+  (and (eq_attr "cpu" "gs264e")
+       (eq_attr "type" "arith,clz,const,logical,
+			move,nop,shift,signext,slt"))
+  "gs264e_alu1")
+
+(define_insn_reservation "gs264e_branch" 1
+  (and (eq_attr "cpu" "gs264e")
+       (eq_attr "type" "branch,jump,call,condmove,trap"))
+  "gs264e_alu1")
+
+(define_insn_reservation "gs264e_mfhilo" 1
+  (and (eq_attr "cpu" "gs264e")
+       (eq_attr "type" "mfhi,mflo,mthi,mtlo"))
+  "gs264e_alu1")
+
+;; Operation imul3nc is fully pipelined.
+(define_insn_reservation "gs264e_imul3nc" 7
+  (and (eq_attr "cpu" "gs264e")
+       (eq_attr "type" "imul3nc"))
+  "gs264e_alu1")
+
+(define_insn_reservation "gs264e_imul" 7
+  (and (eq_attr "cpu" "gs264e")
+       (eq_attr "type" "imul,imadd"))
+  "gs264e_alu1")
+
+(define_insn_reservation "gs264e_idiv_si" 12
+  (and (eq_attr "cpu" "gs264e")
+       (and (eq_attr "type" "idiv")
+	    (eq_attr "mode" "SI")))
+  "gs264e_alu1")
+
+(define_insn_reservation "gs264e_idiv_di" 25
+  (and (eq_attr "cpu" "gs264e")
+       (and (eq_attr "type" "idiv")
+	    (eq_attr "mode" "DI")))
+  "gs264e_alu1")
+
+(define_insn_reservation "gs264e_load" 4
+  (and (eq_attr "cpu" "gs264e")
+       (eq_attr "type" "load"))
+  "gs264e_mem1")
+
+(define_insn_reservation "gs264e_fpload" 4
+  (and (eq_attr "cpu" "gs264e")
+       (eq_attr "type" "load,mfc,mtc"))
+  "gs264e_mem1")
+
+(define_insn_reservation "gs264e_prefetch" 0
+  (and (eq_attr "cpu" "gs264e")
+       (eq_attr "type" "prefetch,prefetchx"))
+  "gs264e_mem1")
+
+(define_insn_reservation "gs264e_store" 0
+  (and (eq_attr "cpu" "gs264e")
+       (eq_attr "type" "store,fpstore,fpidxstore"))
+  "gs264e_mem1")
+
+(define_insn_reservation "gs264e_fadd" 4
+  (and (eq_attr "cpu" "gs264e")
+       (eq_attr "type" "fadd,fmul,fmadd"))
+  "gs264e_falu1")
+
+(define_insn_reservation "gs264e_fcmp" 2
+  (and (eq_attr "cpu" "gs264e")
+       (eq_attr "type" "fabs,fcmp,fmove,fneg"))
+  "gs264e_falu1")
+
+(define_insn_reservation "gs264e_fcvt" 4
+  (and (eq_attr "cpu" "gs264e")
+       (eq_attr "type" "fcvt"))
+  "gs264e_falu1")
+
+(define_insn_reservation "gs264e_fdiv_sf" 12
+  (and (eq_attr "cpu" "gs264e")
+       (and (eq_attr "type" "fdiv,frdiv,fsqrt,frsqrt")
+	    (eq_attr "mode" "SF")))
+  "gs264e_falu1")
+
+(define_insn_reservation "gs264e_fdiv_df" 19
+  (and (eq_attr "cpu" "gs264e")
+       (and (eq_attr "type" "fdiv,frdiv,fsqrt,frsqrt")
+	    (eq_attr "mode" "DF")))
+  "gs264e_falu1")
+
+;; Force single-dispatch for unknown or multi.
+(define_insn_reservation "gs264e_unknown" 1
+  (and (eq_attr "cpu" "gs264e")
+       (eq_attr "type" "unknown,multi,atomic,syncloop"))
+  "gs264e_alu1 + gs264e_falu1 + gs264e_mem1")
+
+;; End of DFA-based pipeline description for gs264e
diff --git a/gcc/config/mips/mips-cpus.def b/gcc/config/mips/mips-cpus.def
index b05b455c3c5..747739f4b90 100644
--- a/gcc/config/mips/mips-cpus.def
+++ b/gcc/config/mips/mips-cpus.def
@@ -165,6 +165,7 @@ MIPS_CPU ("xlr", PROCESSOR_XLR, 64, PTF_AVOID_BRANCHLIKELY_SPEED)
 MIPS_CPU ("loongson3a", PROCESSOR_GS464, 65, PTF_AVOID_BRANCHLIKELY_SPEED)
 MIPS_CPU ("gs464", PROCESSOR_GS464, 65, PTF_AVOID_BRANCHLIKELY_SPEED)
 MIPS_CPU ("gs464e", PROCESSOR_GS464E, 65, PTF_AVOID_BRANCHLIKELY_SPEED)
+MIPS_CPU ("gs264e", PROCESSOR_GS264E, 65, PTF_AVOID_BRANCHLIKELY_SPEED)
 MIPS_CPU ("octeon", PROCESSOR_OCTEON, 65, PTF_AVOID_BRANCHLIKELY_SPEED)
 MIPS_CPU ("octeon+", PROCESSOR_OCTEON, 65, PTF_AVOID_BRANCHLIKELY_SPEED)
 MIPS_CPU ("octeon2", PROCESSOR_OCTEON2, 65, PTF_AVOID_BRANCHLIKELY_SPEED)
diff --git a/gcc/config/mips/mips-tables.opt b/gcc/config/mips/mips-tables.opt
index 539266aec89..7ab2cf5414b 100644
--- a/gcc/config/mips/mips-tables.opt
+++ b/gcc/config/mips/mips-tables.opt
@@ -685,26 +685,29 @@ EnumValue
 Enum(mips_arch_opt_value) String(gs464e) Value(98) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(octeon) Value(99) Canonical
+Enum(mips_arch_opt_value) String(gs264e) Value(99) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(octeon+) Value(100) Canonical
+Enum(mips_arch_opt_value) String(octeon) Value(100) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(octeon2) Value(101) Canonical
+Enum(mips_arch_opt_value) String(octeon+) Value(101) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(octeon3) Value(102) Canonical
+Enum(mips_arch_opt_value) String(octeon2) Value(102) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(xlp) Value(103) Canonical
+Enum(mips_arch_opt_value) String(octeon3) Value(103) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(i6400) Value(104) Canonical
+Enum(mips_arch_opt_value) String(xlp) Value(104) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(i6500) Value(105) Canonical
+Enum(mips_arch_opt_value) String(i6400) Value(105) Canonical
 
 EnumValue
-Enum(mips_arch_opt_value) String(p6600) Value(106) Canonical
+Enum(mips_arch_opt_value) String(i6500) Value(106) Canonical
+
+EnumValue
+Enum(mips_arch_opt_value) String(p6600) Value(107) Canonical
 
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index e6fd0ca4a41..cf157776d2d 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -842,6 +842,9 @@ static const struct mips_rtx_cost_data
   { /* Loongson gs464e.  */
     DEFAULT_COSTS
   },
+  { /* Loongson gs264e.  */
+    DEFAULT_COSTS
+  },
   { /* M4k */
     DEFAULT_COSTS
   },
@@ -14605,6 +14608,7 @@ mips_issue_rate (void)
     case PROCESSOR_OCTEON2:
     case PROCESSOR_OCTEON3:
     case PROCESSOR_I6400:
+    case PROCESSOR_GS264E:
       return 2;
 
     case PROCESSOR_SB1:
@@ -14753,7 +14757,7 @@ mips_multipass_dfa_lookahead (void)
   if (TUNE_LOONGSON_2EF || TUNE_GS464 || TUNE_GS464E)
     return 4;
 
-  if (TUNE_OCTEON)
+  if (TUNE_OCTEON || TUNE_GS264E)
     return 2;
 
   if (TUNE_P5600 || TUNE_P6600 || TUNE_I6400)
@@ -20175,28 +20179,37 @@ mips_option_override (void)
   if (TARGET_LOONGSON_MMI &&  !TARGET_HARD_FLOAT_ABI)
     error ("%<-mloongson-mmi%> must be used with %<-mhard-float%>");
 
-  /* Default to enable Loongson MMI on Longson 2e, 2f, gs464
-   * or gs464e target.  */
+  /* Default to enable Loongson MMI on Longson 2e, 2f, gs464, gs464e
+   * or gs264e target.  */
   if ((target_flags_explicit & MASK_LOONGSON_MMI) == 0
       && ((strcmp (mips_arch_info->name, "loongson2e") == 0)
 	  || (strcmp (mips_arch_info->name, "loongson2f") == 0)
 	  || (strcmp (mips_arch_info->name, "loongson3a") == 0)
 	  || (strcmp (mips_arch_info->name, "gs464") == 0)
-	  || (strcmp (mips_arch_info->name, "gs464e") == 0)))
+	  || (strcmp (mips_arch_info->name, "gs464e") == 0)
+	  || (strcmp (mips_arch_info->name, "gs264e") == 0)))
     target_flags |= MASK_LOONGSON_MMI;
 
-  /* Default to enable Loongson EXT on Longson gs464 or gs464e target.  */
+  /* Default to enable Loongson EXT on Longson gs464, gs464e
+   * or gs264e target.  */
   if ((target_flags_explicit & MASK_LOONGSON_EXT) == 0
       && ((strcmp (mips_arch_info->name, "loongson3a") == 0)
 	  || (strcmp (mips_arch_info->name, "gs464") == 0)
-	  || (strcmp (mips_arch_info->name, "gs464e") == 0)))
+	  || (strcmp (mips_arch_info->name, "gs464e") == 0)
+	  || (strcmp (mips_arch_info->name, "gs264e") == 0)))
     target_flags |= MASK_LOONGSON_EXT;
 
-  /* Default to enable Loongson EXT2 on gs464e target.  */
+  /* Default to enable Loongson EXT2 on gs464e or gs264e target.  */
   if ((target_flags_explicit & MASK_LOONGSON_EXT2) == 0
-      && (strcmp (mips_arch_info->name, "gs464e") == 0))
+      && ((strcmp (mips_arch_info->name, "gs464e") == 0)
+	  || (strcmp (mips_arch_info->name, "gs264e") == 0)))
     target_flags |= MASK_LOONGSON_EXT2;
 
+  /* Default to enable MSA on gs264e target.  */
+  if ((target_flags_explicit & MASK_MSA) == 0
+      && (strcmp (mips_arch_info->name, "gs264e") == 0))
+    target_flags |= MASK_MSA;
+
   /* .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 b4bb4498572..5953594af0b 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -268,6 +268,7 @@ struct mips_cpu_info {
 #define TARGET_LOONGSON_2EF         (TARGET_LOONGSON_2E || TARGET_LOONGSON_2F)
 #define TARGET_GS464		    (mips_arch == PROCESSOR_GS464)
 #define TARGET_GS464E		    (mips_arch == PROCESSOR_GS464E)
+#define TARGET_GS264E		    (mips_arch == PROCESSOR_GS264E)
 #define TARGET_MIPS3900             (mips_arch == PROCESSOR_R3900)
 #define TARGET_MIPS4000             (mips_arch == PROCESSOR_R4000)
 #define TARGET_MIPS4120             (mips_arch == PROCESSOR_R4120)
@@ -301,6 +302,7 @@ struct mips_cpu_info {
 				     || mips_tune == PROCESSOR_LOONGSON_2F)
 #define TUNE_GS464		    (mips_tune == PROCESSOR_GS464)
 #define TUNE_GS464E		    (mips_tune == PROCESSOR_GS464E)
+#define TUNE_GS264E		    (mips_tune == PROCESSOR_GS264E)
 #define TUNE_MIPS3000               (mips_tune == PROCESSOR_R3000)
 #define TUNE_MIPS3900               (mips_tune == PROCESSOR_R3900)
 #define TUNE_MIPS4000               (mips_tune == PROCESSOR_R4000)
@@ -792,8 +794,8 @@ struct mips_cpu_info {
      %{march=mips32r6: -mips32r6} \
      %{march=mips64|march=5k*|march=20k*|march=sb1*|march=sr71000 \
        |march=xlr: -mips64} \
-     %{march=mips64r2|march=loongson3a|march=gs464|march=gs464e|march=octeon \
-       |march=xlp: -mips64r2} \
+     %{march=mips64r2|march=loongson3a|march=gs464|march=gs464e|march=gs264e \
+       |march=octeon|march=xlp: -mips64r2} \
      %{march=mips64r3: -mips64r3} \
      %{march=mips64r5: -mips64r5} \
      %{march=mips64r6|march=i6400|march=i6500|march=p6600: -mips64r6}}"
@@ -1086,7 +1088,8 @@ struct mips_cpu_info {
 #define ISA_HAS_FUSED_MADD4	(mips_madd4				\
 				 && (TARGET_MIPS8000			\
 				     || TARGET_GS464			\
-				     || TARGET_GS464E))
+				     || TARGET_GS464E			\
+				     || TARGET_GS264E))
 
 /* ISA has 4 operand unfused madd instructions of the form
    'd = [+-] (a * b [+-] c)'.  */
@@ -1094,7 +1097,8 @@ struct mips_cpu_info {
 				 && ISA_HAS_FP4				\
 				 && !TARGET_MIPS8000			\
 				 && !TARGET_GS464			\
-				 && !TARGET_GS464E)
+				 && !TARGET_GS464E			\
+				 && !TARGET_GS264E)
 
 /* ISA has 3 operand r6 fused madd instructions of the form
    'c = c [+-] (a * b)'.  */
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index 15f0e479552..6ff75ea9c81 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -39,6 +39,7 @@
   loongson_2f
   gs464
   gs464e
+  gs264e
   m4k
   octeon
   octeon2
@@ -1177,6 +1178,7 @@
 (include "loongson2ef.md")
 (include "gs464.md")
 (include "gs464e.md")
+(include "gs264e.md")
 (include "octeon.md")
 (include "sb1.md")
 (include "sr71k.md")
diff --git a/gcc/config/mips/mips.opt b/gcc/config/mips/mips.opt
index c0c8005b025..16c33d12e22 100644
--- a/gcc/config/mips/mips.opt
+++ b/gcc/config/mips/mips.opt
@@ -300,7 +300,7 @@ Target Report Mask(MICROMIPS)
 Use microMIPS instructions.
 
 mmsa
-Target Report Var(TARGET_MSA)
+Target Report Mask(MSA)
 Use MIPS MSA Extension instructions.
 
 mmt
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index ed97bc9ac0b..5b5dd8aac6e 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -20769,6 +20769,7 @@ The processor names are:
 @samp{i6400}, @samp{i6500},
 @samp{interaptiv},
 @samp{loongson2e}, @samp{loongson2f}, @samp{gs464}, @samp{gs464e},
+@samp{gs264e},
 @samp{m4k},
 @samp{m14k}, @samp{m14kc}, @samp{m14ke}, @samp{m14kec},
 @samp{m5100}, @samp{m5101},
-- 
2.11.0

