public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH][MIPS] Add Global INValidate instructions
@ 2017-11-27 22:46 Faraz Shahbazker
  2017-11-29 19:17 ` Faraz Shahbazker
  0 siblings, 1 reply; 5+ messages in thread
From: Faraz Shahbazker @ 2017-11-27 22:46 UTC (permalink / raw)
  To: binutils, macro; +Cc: Matthew Fortune

The following patch adds support for the Global INValidate (GINV)
instructions in Release 6 of the MIPS Architecture.  The changes are:
* New instruction GINVI, GINVT: enabled by option `-mginv'.
* New instruction GINVGT: enabled by `-mginv -mvirt'.
* Bit-17 in MIPS.abiflags is set when GINV extension is enabled.

The new ginv* instructions are described in Section 3.2 of the MIPS
Instruction Set v6.06
(https://www.mips.com/?do-download=the-mips32-instruction-set-v6-06)

This patch cannot be committed yet, since copyright assignment to FSF
from the new MIPS entity is still pending. Please review and approve
for a future commit.

Regards,
Faraz Shahbazker

ChangeLog:

bfd/
	* elfxx-mips.c (print_mips_ases): Add GINV extension.

binutils/
	* readelf.c (print_mips_ases) Add GINV extension.

gas/
	* config/tc-mips.c (options) <OPTION_GINV,  OPTION_NOGINV>:
	New.
	(md_longopts): Add -m[no-]ginv options.
	(mips_ases): Likewise.
	(mips_set_ase): Handle combination of VX and GINV extensions.
	(mips_convert_ase_flags): Add GINV extension.
	(md_show_usage): Add -m[no-]ginv options.
	* doc/as.texinfo: Add description for -m[no-]ginv.
	* doc/c-mips.texi: Likewise.

include/
	* elf/mips.h (AFL_ASE_GINV): New.
	(AFL_ASE_MASK): Update mask for all ASEs.

	* opcode/mips.h: Comments describing new MIPS and micromips
	operand format "+\".
	(ASE_GINV): New.
	(ASE_GINV_VIRT): Likewise.

opcodes/
	* mips-opc.c (decode_mips_operand) <+\>: New case.
	(GINV): New.
	(GINVVZ): Likewise.
	(mips_opcodes): Add instructions GINVI,  GINVT,  GINVGT.

	* micromips-opc.c (decode_micromips_operand) <+\>: New case.
	(GINV): New.
	(GINVVZ): Likewise.
	(micromips_opcodes): Add instructions GINVI,  GINVT,  GINVGT.

	* mips-dis.c (mips_arch_choices): Add GINV and VIRT_GINV ASEs
	to mips32r6 and mips64r6 descriptors.
	(mips_calculate_combination_ases): Set VIRT_GINV appropriately.
	(parse_mips_ase_option): Handle -mginv option.

gas/testsuite/
	* gas/mips/mips.exp: Add new tests.
	* gas/mips/ase-errors-1.s: Add new test cases.
	* gas/mips/ase-errors-2.s: Likewise.
	* gas/mips/ginv.s: New file.
	* gas/mips/ginv-error.s: Likewise.
	* gas/mips/ginv-virt-error.s: Likewise.
	* gas/mips/ginv.d: Likewise.
	* gas/mips/ginv-dis.d: Likewise.
	* gas/mips/ginv-virt.d: Likewise.
	* gas/mips/ginv-virt-dis.d: Likewise.
	* gas/mips/micromipsr@ginv.d: Likewise.
	* gas/mips/micromipsr@ginv-dis.d: Likewise.
	* gas/mips/micromipsr@ginv-virt.d: Likewise.
	* gas/mips/micromipsr@ginv-virt-dis.d: Likewise.
	* gas/mips/ase-errors-1.l: Update reference output.
	* gas/mips/ase-errors-2.l: Likewise.
	* gas/mips/ginv-error.l: New file.
	* gas/mips/ginv-virt-error.l: New file.
---
  bfd/elfxx-mips.c                                 |  2 ++
  binutils/readelf.c                               |  2 ++
  gas/config/tc-mips.c                             | 25 
+++++++++++++++++++++++-
  gas/doc/as.texinfo                               |  7 +++++++
  gas/doc/c-mips.texi                              |  6 ++++++
  gas/testsuite/gas/mips/ase-errors-1.l            |  6 ++++++
  gas/testsuite/gas/mips/ase-errors-1.s            | 13 ++++++++++++
  gas/testsuite/gas/mips/ase-errors-2.l            |  6 ++++++
  gas/testsuite/gas/mips/ase-errors-2.s            | 13 ++++++++++++
  gas/testsuite/gas/mips/ginv-dis.d                | 15 ++++++++++++++
  gas/testsuite/gas/mips/ginv-error.l              |  2 ++
  gas/testsuite/gas/mips/ginv-error.s              |  8 ++++++++
  gas/testsuite/gas/mips/ginv-virt-dis.d           | 17 ++++++++++++++++
  gas/testsuite/gas/mips/ginv-virt-error.l         |  3 +++
  gas/testsuite/gas/mips/ginv-virt-error.s         | 10 ++++++++++
  gas/testsuite/gas/mips/ginv-virt.d               | 17 ++++++++++++++++
  gas/testsuite/gas/mips/ginv.d                    | 14 +++++++++++++
  gas/testsuite/gas/mips/ginv.s                    | 13 ++++++++++++
  gas/testsuite/gas/mips/micromips@ginv-dis.d      | 16 +++++++++++++++
  gas/testsuite/gas/mips/micromips@ginv-virt-dis.d | 17 ++++++++++++++++
  gas/testsuite/gas/mips/micromips@ginv-virt.d     | 17 ++++++++++++++++
  gas/testsuite/gas/mips/micromips@ginv.d          | 16 +++++++++++++++
  gas/testsuite/gas/mips/mips.exp                  |  8 ++++++++
  include/elf/mips.h                               |  3 ++-
  include/opcode/mips.h                            | 11 +++++++++++
  opcodes/micromips-opc.c                          | 11 +++++++++++
  opcodes/mips-dis.c                               | 12 ++++++++++--
  opcodes/mips-opc.c                               |  9 +++++++++
  28 files changed, 295 insertions(+), 4 deletions(-)
  create mode 100644 gas/testsuite/gas/mips/ginv-dis.d
  create mode 100644 gas/testsuite/gas/mips/ginv-error.l
  create mode 100644 gas/testsuite/gas/mips/ginv-error.s
  create mode 100644 gas/testsuite/gas/mips/ginv-virt-dis.d
  create mode 100644 gas/testsuite/gas/mips/ginv-virt-error.l
  create mode 100644 gas/testsuite/gas/mips/ginv-virt-error.s
  create mode 100644 gas/testsuite/gas/mips/ginv-virt.d
  create mode 100644 gas/testsuite/gas/mips/ginv.d
  create mode 100644 gas/testsuite/gas/mips/ginv.s
  create mode 100644 gas/testsuite/gas/mips/micromips@ginv-dis.d
  create mode 100644 gas/testsuite/gas/mips/micromips@ginv-virt-dis.d
  create mode 100644 gas/testsuite/gas/mips/micromips@ginv-virt.d
  create mode 100644 gas/testsuite/gas/mips/micromips@ginv.d

diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
index c3b8ec9..d703171 100644
--- a/bfd/elfxx-mips.c
+++ b/bfd/elfxx-mips.c
@@ -15613,6 +15613,8 @@ print_mips_ases (FILE *file, unsigned int mask)
      fputs ("\n\tXPA ASE", file);
    if (mask & AFL_ASE_MIPS16E2)
      fputs ("\n\tMIPS16e2 ASE", file);
+  if (mask & AFL_ASE_GINV)
+    fputs ("\n\tGINV ASE", file);
    if (mask == 0)
      fprintf (file, "\n\t%s", _("None"));
    else if ((mask & ~AFL_ASE_MASK) != 0)
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 739367d..3866512 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -15412,6 +15412,8 @@ print_mips_ases (unsigned int mask)
      fputs ("\n\tXPA ASE", stdout);
    if (mask & AFL_ASE_MIPS16E2)
      fputs ("\n\tMIPS16e2 ASE", stdout);
+  if (mask & AFL_ASE_GINV)
+    fputs ("\n\tGINV ASE", stdout);
    if (mask == 0)
      fprintf (stdout, "\n\t%s", _("None"));
    else if ((mask & ~AFL_ASE_MASK) != 0)
diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
index 040a373..f4b1e2d 100644
--- a/gas/config/tc-mips.c
+++ b/gas/config/tc-mips.c
@@ -1526,6 +1526,8 @@ enum options
      OPTION_NAN,
      OPTION_ODD_SPREG,
      OPTION_NO_ODD_SPREG,
+    OPTION_GINV,
+    OPTION_NO_GINV,
      OPTION_END_OF_ENUM
    };

@@ -1582,6 +1584,8 @@ struct option md_longopts[] =
    {"mno-xpa", no_argument, NULL, OPTION_NO_XPA},
    {"mmips16e2", no_argument, NULL, OPTION_MIPS16E2},
    {"mno-mips16e2", no_argument, NULL, OPTION_NO_MIPS16E2},
+  {"mginv", no_argument, NULL, OPTION_GINV},
+  {"mno-ginv", no_argument, NULL, OPTION_NO_GINV},

    /* Old-style architecture options.  Don't add more of these.  */
    {"m4650", no_argument, NULL, OPTION_M4650},
@@ -1769,6 +1773,11 @@ static const struct mips_ase mips_ases[] = {
      OPTION_MIPS16E2, OPTION_NO_MIPS16E2,
      2,  2, -1, -1,
      6 },
+
+  { "ginv", ASE_GINV, 0,
+    OPTION_GINV, OPTION_NO_GINV,
+    6,  6, 6, 6,
+    -1 },
  };

  /* The set of ASEs that require -mfp64.  */
@@ -2133,7 +2142,7 @@ mips_set_ase (const struct mips_ase *ase, struct 
mips_set_options *opts,

    /* Clear combination ASE flags, which need to be recalculated based on
       updated regular ASE settings.  */
-  opts->ase &= ~(ASE_MIPS16E2_MT | ASE_XPA_VIRT);
+  opts->ase &= ~(ASE_MIPS16E2_MT | ASE_XPA_VIRT | ASE_GINV_VIRT);

    if (enabled_p)
      opts->ase |= ase->flags;
@@ -2152,6 +2161,15 @@ mips_set_ase (const struct mips_ase *ase, struct 
mips_set_options *opts,
        mask |= ASE_MIPS16E2_MT;
      }

+  /* The Virtualization ASE has Global INValidate (GINV)
+     instructions which are only valid when both ASEs are enabled.
+     This sets the ASE_GINV_VIRT flag when both ASEs are present.  */
+  if ((opts->ase & (ASE_GINV | ASE_VIRT)) == (ASE_GINV | ASE_VIRT))
+    {
+      opts->ase |= ASE_GINV_VIRT;
+      mask |= ASE_GINV_VIRT;
+    }
+
    return mask;
  }

@@ -18977,6 +18995,8 @@ mips_convert_ase_flags (int ase)
      ext_ases |= AFL_ASE_XPA;
    if (ase & ASE_MIPS16E2)
      ext_ases |= file_ase_mips16 ? AFL_ASE_MIPS16E2 : 0;
+  if (ase & ASE_GINV)
+    ext_ases |= AFL_ASE_GINV;

    return ext_ases;
  }
@@ -19988,6 +20008,9 @@ MIPS options:\n\
  -mvirt			generate Virtualization instructions\n\
  -mno-virt		do not generate Virtualization instructions\n"));
    fprintf (stream, _("\
+-mginv			generate Global INValidate (GINV) instructions\n\
+-mno-ginv		do not generate Global INValidate instructions\n"));
+  fprintf (stream, _("\
  -minsn32		only generate 32-bit microMIPS instructions\n\
  -mno-insn32		generate all microMIPS instructions\n"));
    fprintf (stream, _("\
diff --git a/gas/doc/as.texinfo b/gas/doc/as.texinfo
index d37a1d6..700208f 100644
--- a/gas/doc/as.texinfo
+++ b/gas/doc/as.texinfo
@@ -432,6 +432,7 @@ gcc(1), ld(1), and the Info entries for 
@file{binutils} and @file{ld}.
     [@b{-mxpa}] [@b{-mno-xpa}]
     [@b{-mmt}] [@b{-mno-mt}]
     [@b{-mmcu}] [@b{-mno-mcu}]
+   [@b{-mginv}] [@b{-mno-ginv}]
     [@b{-minsn32}] [@b{-mno-insn32}]
     [@b{-mfix7000}] [@b{-mno-fix7000}]
     [@b{-mfix-rm7000}] [@b{-mno-fix-rm7000}]
@@ -1531,6 +1532,12 @@ Generate code for the MCU Application Specific 
Extension.
  This tells the assembler to accept MCU instructions.
  @samp{-mno-mcu} turns off this option.

+@item -mginv
+@itemx -mno-ginv
+Generate code for the Global INValidate (GINV) Application Specific
+Extension.  This tells the assembler to accept GINV instructions.
+@samp{-mno-ginv} turns off this option.
+
  @item -minsn32
  @itemx -mno-insn32
  Only use 32-bit instruction encodings when generating code for the
diff --git a/gas/doc/c-mips.texi b/gas/doc/c-mips.texi
index a430b0d..66b8f94 100644
--- a/gas/doc/c-mips.texi
+++ b/gas/doc/c-mips.texi
@@ -234,6 +234,12 @@ Generate code for the Virtualization Application 
Specific Extension.
  This tells the assembler to accept Virtualization instructions.
  @samp{-mno-virt} turns off this option.

+@item -mginv
+@itemx -mno-ginv
+Generate code for the Global INValidate (GINV) Application Specific
+Extension.  This tells the assembler to accept GINV instructions.
+@samp{-mno-ginv} turns off this option.
+
  @item -minsn32
  @itemx -mno-insn32
  Only use 32-bit instruction encodings when generating code for the
diff --git a/gas/testsuite/gas/mips/ase-errors-1.l 
b/gas/testsuite/gas/mips/ase-errors-1.l
index f989982..2c48f0b 100644
--- a/gas/testsuite/gas/mips/ase-errors-1.l
+++ b/gas/testsuite/gas/mips/ase-errors-1.l
@@ -40,3 +40,9 @@
  # 
----------------------------------------------------------------------------
  .*:100: Warning: the `eva' extension requires MIPS32 revision 2 or greater
  .*:103: Error: opcode not supported.* `lbue \$4,16\(\$5\)'
+# 
----------------------------------------------------------------------------
+.*:108: Error: invalid operands `ginvt \$f0,\$f1'
+.*:109: Warning: the `ginv' extension requires MIPS32 revision 6 or greater
+.*:114: Error: opcode not supported.* `ginvgt \$a1,3'
+.*:116: Error: opcode not supported.* `ginvi \$a0'
+# 
----------------------------------------------------------------------------
diff --git a/gas/testsuite/gas/mips/ase-errors-1.s 
b/gas/testsuite/gas/mips/ase-errors-1.s
index c5201c3..82eee29 100644
--- a/gas/testsuite/gas/mips/ase-errors-1.s
+++ b/gas/testsuite/gas/mips/ase-errors-1.s
@@ -102,6 +102,19 @@
  	.set noeva
  	lbue $4,16($5)		# ERROR: eva not enabled

+	.set mips32r6
+	.set ginv		# OK
+	ginvi		$a0	# OK
+	ginvt 		$f0,$f1	# ERROR: Invalid operands
+	.set mips32r5		# ERROR: too low
+	ginvt		$a0,1	# OK
+	.set virt
+	ginvgt		$a0, 2	# OK
+	.set novirt
+	ginvgt		$a1, 3	# ERROR: virt not enabled
+	.set noginv
+	ginvi		$a0	# ERROR: crypto not enabled
+
  	# There should be no errors after this.
  	.set fp=32
  	.set mips1
diff --git a/gas/testsuite/gas/mips/ase-errors-2.l 
b/gas/testsuite/gas/mips/ase-errors-2.l
index 4c24690..b29c858 100644
--- a/gas/testsuite/gas/mips/ase-errors-2.l
+++ b/gas/testsuite/gas/mips/ase-errors-2.l
@@ -32,3 +32,9 @@
  # 
----------------------------------------------------------------------------
  .*:84: Warning: the `eva' extension requires MIPS64 revision 2 or greater
  .*:87: Error: opcode not supported.* `lbue \$4,16\(\$5\)'
+# 
----------------------------------------------------------------------------
+.*:92: Error: invalid operands `ginvt \$f0,\$f1'
+.*:93: Warning: the `ginv' extension requires MIPS64 revision 6 or greater
+.*:98: Error: opcode not supported.* `ginvgt \$a1,3'
+.*:100: Error: opcode not supported.* `ginvi \$a0'
+# 
----------------------------------------------------------------------------
diff --git a/gas/testsuite/gas/mips/ase-errors-2.s 
b/gas/testsuite/gas/mips/ase-errors-2.s
index 4a17e4f..1312eb0 100644
--- a/gas/testsuite/gas/mips/ase-errors-2.s
+++ b/gas/testsuite/gas/mips/ase-errors-2.s
@@ -86,6 +86,19 @@
  	.set noeva
  	lbue $4,16($5)		# ERROR: eva not enabled

+	.set mips64r6
+	.set ginv		# OK
+	ginvi		$a0	# OK
+	ginvt 		$f0,$f1	# ERROR: Invalid operands
+	.set mips64r5		# ERROR: too low
+	ginvt		$a0,1	# OK
+	.set virt
+	ginvgt		$a0, 2	# OK
+	.set novirt
+	ginvgt		$a1, 3	# ERROR: virt not enabled
+	.set noginv
+	ginvi		$a0	# ERROR: crypto not enabled
+
  	# There should be no errors after this.
  	.set fp=32
  	.set mips4
diff --git a/gas/testsuite/gas/mips/ginv-dis.d 
b/gas/testsuite/gas/mips/ginv-dis.d
new file mode 100644
index 0000000..4738b5d
--- /dev/null
+++ b/gas/testsuite/gas/mips/ginv-dis.d
@@ -0,0 +1,15 @@
+#objdump: -Mginv -d --show-raw-insn
+#name: MIPS Global INValidate instructions disassembly
+#as: -mginv
+#source: ginv.s
+
+# Check MIPS Global INValidate instructions
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+00000000 <test>:
+   0:	7c40003d 	ginvi	v0
+   4:	7c6000bd 	ginvt	v1,0x0
+   8:	7c8001bd 	ginvt	a0,0x1
+	\.\.\.
diff --git a/gas/testsuite/gas/mips/ginv-error.l 
b/gas/testsuite/gas/mips/ginv-error.l
new file mode 100644
index 0000000..75e60e8
--- /dev/null
+++ b/gas/testsuite/gas/mips/ginv-error.l
@@ -0,0 +1,2 @@
+.*ginv-error.s: Assembler messages:
+.*ginv-error.s:3: Warning: the `ginv' extension requires MIPS32 
revision 6 or greater
diff --git a/gas/testsuite/gas/mips/ginv-error.s 
b/gas/testsuite/gas/mips/ginv-error.s
new file mode 100644
index 0000000..1739be8
--- /dev/null
+++ b/gas/testsuite/gas/mips/ginv-error.s
@@ -0,0 +1,8 @@
+	.text
+test:
+	ginvi	$2
+	ginvt	$3,0
+	ginvt	$4,1
+
+	.align	2
+	.space	8
diff --git a/gas/testsuite/gas/mips/ginv-virt-dis.d 
b/gas/testsuite/gas/mips/ginv-virt-dis.d
new file mode 100644
index 0000000..bd07a3b
--- /dev/null
+++ b/gas/testsuite/gas/mips/ginv-virt-dis.d
@@ -0,0 +1,17 @@
+#objdump: -Mginv -Mvirt -d --show-raw-insn
+#name: MIPS GINV+VIRT disassembly
+#as: --defsym VX=1 -mginv -mvirt
+#source: ginv.s
+
+# Check MIPS Global INValidate Virtualization disassembly
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+00000000 <test>:
+   0:	7c40003d 	ginvi	v0
+   4:	7c6000bd 	ginvt	v1,0x0
+   8:	7c8001bd 	ginvt	a0,0x1
+   c:	7ca002fd 	ginvgt	a1,0x2
+  10:	7cc003fd 	ginvgt	a2,0x3
+	\.\.\.
diff --git a/gas/testsuite/gas/mips/ginv-virt-error.l 
b/gas/testsuite/gas/mips/ginv-virt-error.l
new file mode 100644
index 0000000..9fe7a30
--- /dev/null
+++ b/gas/testsuite/gas/mips/ginv-virt-error.l
@@ -0,0 +1,3 @@
+.*ginv-virt-error.s: Assembler messages:
+.*ginv-virt-error.s:6: Error: opcode not supported on this processor: 
mips32r6 \(mips32r6\) `ginvgt \$5,2'
+.*ginv-virt-error.s:7: Error: opcode not supported on this processor: 
mips32r6 \(mips32r6\) `ginvgt \$6,3'
diff --git a/gas/testsuite/gas/mips/ginv-virt-error.s 
b/gas/testsuite/gas/mips/ginv-virt-error.s
new file mode 100644
index 0000000..b9a201b
--- /dev/null
+++ b/gas/testsuite/gas/mips/ginv-virt-error.s
@@ -0,0 +1,10 @@
+	.text
+test:
+	ginvi	$2
+	ginvt	$3,0
+	ginvt	$4,1
+	ginvgt	$5,2
+	ginvgt	$6,3
+
+	.align	2
+	.space	8
diff --git a/gas/testsuite/gas/mips/ginv-virt.d 
b/gas/testsuite/gas/mips/ginv-virt.d
new file mode 100644
index 0000000..6390dc8
--- /dev/null
+++ b/gas/testsuite/gas/mips/ginv-virt.d
@@ -0,0 +1,17 @@
+#objdump: -d --show-raw-insn
+#name: MIPS Global INValidate Virtualization instructions
+#as: --defsym VX= -mginv -mvirt
+#source: ginv.s
+
+# Check MIPS Global INValidate Virtualization instructions
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+00000000 <test>:
+   0:	7c40003d 	ginvi	v0
+   4:	7c6000bd 	ginvt	v1,0x0
+   8:	7c8001bd 	ginvt	a0,0x1
+   c:	7ca002fd 	ginvgt	a1,0x2
+  10:	7cc003fd 	ginvgt	a2,0x3
+	\.\.\.
diff --git a/gas/testsuite/gas/mips/ginv.d b/gas/testsuite/gas/mips/ginv.d
new file mode 100644
index 0000000..0cc3c2d
--- /dev/null
+++ b/gas/testsuite/gas/mips/ginv.d
@@ -0,0 +1,14 @@
+#objdump: -d --show-raw-insn
+#name: MIPS Global INValidate instructions
+#as: -mginv
+
+# Check MIPS Global INValidate instructions
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+00000000 <test>:
+   0:	7c40003d 	ginvi	v0
+   4:	7c6000bd 	ginvt	v1,0x0
+   8:	7c8001bd 	ginvt	a0,0x1
+	\.\.\.
diff --git a/gas/testsuite/gas/mips/ginv.s b/gas/testsuite/gas/mips/ginv.s
new file mode 100644
index 0000000..e9f12ab
--- /dev/null
+++ b/gas/testsuite/gas/mips/ginv.s
@@ -0,0 +1,13 @@
+	.text
+test:
+	ginvi	$2
+	ginvt	$3,0
+	ginvt	$4,1
+
+	.ifdef VX
+	ginvgt	$5,2
+	ginvgt	$6,3
+	.endif
+
+	.align	2
+	.space	8
diff --git a/gas/testsuite/gas/mips/micromips@ginv-dis.d 
b/gas/testsuite/gas/mips/micromips@ginv-dis.d
new file mode 100644
index 0000000..e2e7000
--- /dev/null
+++ b/gas/testsuite/gas/mips/micromips@ginv-dis.d
@@ -0,0 +1,16 @@
+#objdump: -Mginv -d --show-raw-insn
+#name: MIPS microMIPS Global INValidate disassembly
+#as: -mginv
+#source: ginv.s
+
+# Check microMIPS Global INValidate disassembly
+
+.*: +file format .*mips.*
+
+
+Disassembly of section .text:
+00000000 <test>:
+   0:	0002 617c 	ginvi	v0
+   4:	0003 717c 	ginvt	v1,0x0
+   8:	0004 737c 	ginvt	a0,0x1
+	\.\.\.
diff --git a/gas/testsuite/gas/mips/micromips@ginv-virt-dis.d 
b/gas/testsuite/gas/mips/micromips@ginv-virt-dis.d
new file mode 100644
index 0000000..c0a4acb
--- /dev/null
+++ b/gas/testsuite/gas/mips/micromips@ginv-virt-dis.d
@@ -0,0 +1,17 @@
+#objdump: -mmips:isa32 -Mginv -Mvirt -d --show-raw-insn
+#name: MIPS microMIPS GINV+VIRT instruction disassembly
+#as: --defsym VX= -mginv -mvirt
+#source: ginv.s
+
+# Check microMIPS Global INValidate Virtualization disassembly
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+00000000 <test>:
+   0:	0002 617c 	ginvi	v0
+   4:	0003 717c 	ginvt	v1,0x0
+   8:	0004 737c 	ginvt	a0,0x1
+   c:	0005 7d7c 	ginvgt	a1,0x2
+  10:	0006 7f7c 	ginvgt	a2,0x3
+	\.\.\.
diff --git a/gas/testsuite/gas/mips/micromips@ginv-virt.d 
b/gas/testsuite/gas/mips/micromips@ginv-virt.d
new file mode 100644
index 0000000..08889fb
--- /dev/null
+++ b/gas/testsuite/gas/mips/micromips@ginv-virt.d
@@ -0,0 +1,17 @@
+#objdump: -d --show-raw-insn
+#name: MIPS microMIPS Global INValidate Virtualization instructions
+#as: --defsym VX= -mginv -mvirt
+#source: ginv.s
+
+# Check microMIPS Global INValidate Virtualization instructions
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+00000000 <test>:
+   0:	0002 617c 	ginvi	v0
+   4:	0003 717c 	ginvt	v1,0x0
+   8:	0004 737c 	ginvt	a0,0x1
+   c:	0005 7d7c 	ginvgt	a1,0x2
+  10:	0006 7f7c 	ginvgt	a2,0x3
+	\.\.\.
diff --git a/gas/testsuite/gas/mips/micromips@ginv.d 
b/gas/testsuite/gas/mips/micromips@ginv.d
new file mode 100644
index 0000000..e2e7000
--- /dev/null
+++ b/gas/testsuite/gas/mips/micromips@ginv.d
@@ -0,0 +1,16 @@
+#objdump: -Mginv -d --show-raw-insn
+#name: MIPS microMIPS Global INValidate disassembly
+#as: -mginv
+#source: ginv.s
+
+# Check microMIPS Global INValidate disassembly
+
+.*: +file format .*mips.*
+
+
+Disassembly of section .text:
+00000000 <test>:
+   0:	0002 617c 	ginvi	v0
+   4:	0003 717c 	ginvt	v1,0x0
+   8:	0004 737c 	ginvt	a0,0x1
+	\.\.\.
diff --git a/gas/testsuite/gas/mips/mips.exp 
b/gas/testsuite/gas/mips/mips.exp
index 94c4506..8e2dbc7 100644
--- a/gas/testsuite/gas/mips/mips.exp
+++ b/gas/testsuite/gas/mips/mips.exp
@@ -2050,4 +2050,12 @@ if { [istarget mips*-*-vxworks*] } {

      run_list_test_arches "r6-branch-constraints"  "-32" \
  			[mips_arch_list_matching mips32r6]
+
+    run_dump_test_arches "ginv" "" [mips_arch_list_matching mips32r6]
+    run_dump_test_arches "ginv-virt" "" [mips_arch_list_matching 
micromipsr6]
+    run_dump_test_arches "ginv-dis" "" [mips_arch_list_matching mips32r6]
+    run_dump_test_arches "ginv-virt-dis" "" \
+				[mips_arch_list_matching micromipsr6]
+    run_list_test "ginv-error" "-mips32 -mginv"
+    run_list_test "ginv-virt-error" "-mips32r6 -mginv"
  }
diff --git a/include/elf/mips.h b/include/elf/mips.h
index a4bea43..d98b312 100644
--- a/include/elf/mips.h
+++ b/include/elf/mips.h
@@ -1235,7 +1235,8 @@ extern void bfd_mips_elf_swap_abiflags_v0_out
  #define AFL_ASE_XPA          0x00001000 /* XPA ASE.  */
  #define AFL_ASE_DSPR3        0x00002000 /* DSP R3 ASE.  */
  #define AFL_ASE_MIPS16E2     0x00004000 /* MIPS16e2 ASE.  */
-#define AFL_ASE_MASK         0x00007fff /* All ASEs.  */
+#define AFL_ASE_GINV         0x00020000 /* GINV ASE.  */
+#define AFL_ASE_MASK         0x00027fff /* All ASEs.  */

  /* Values for the isa_ext word of an ABI flags structure.  */

diff --git a/include/opcode/mips.h b/include/opcode/mips.h
index ceae9ec..c163846 100644
--- a/include/opcode/mips.h
+++ b/include/opcode/mips.h
@@ -989,6 +989,9 @@ mips_opcode_32bit_p (const struct mips_opcode *mo)
     "-A" symbolic offset (-262144 .. 262143) << 2 at bit 0
     "-B" symbolic offset (-131072 .. 131071) << 3 at bit 0

+   GINV ASE usage:
+   "+\" 2 bit Global TLB invalidate type at bit 8
+
     Other:
     "()" parens surrounding optional value
     ","  separates operands
@@ -1294,6 +1297,11 @@ static const unsigned int mips_isa_table[] = {
  /* The Virtualization ASE has eXtended Physical Addressing (XPA)
     instructions which are only valid when both ASEs are enabled.  */
  #define ASE_XPA_VIRT		0x00020000
+/* Global INValidate Extension. */
+#define ASE_GINV		0x00800000
+/* The Virtualization ASE has Global INValidate extension instructions
+   which are only valid when both ASEs are enabled. */
+#define ASE_GINV_VIRT		0x01000000

  /* MIPS ISA defines, use instead of hardcoding ISA level.  */

@@ -2308,6 +2316,9 @@ extern const int bfd_mips16_num_opcodes;
     "+*" 5-bit register vector element index at bit 16
     "+|" 8-bit mask at bit 16

+   GINV ASE usage:
+   "+\" 2 bit Global TLB invalidate type at bit 8
+
     Other:
     "()" parens surrounding optional value
     ","  separates operands
diff --git a/opcodes/micromips-opc.c b/opcodes/micromips-opc.c
index d6234af..894c1f2 100644
--- a/opcodes/micromips-opc.c
+++ b/opcodes/micromips-opc.c
@@ -137,6 +137,7 @@ decode_micromips_operand (const char *p)
  	case '&': SPECIAL (0, 0, IMM_INDEX);
  	case '*': SPECIAL (5, 16, REG_INDEX);
  	case '|': BIT (8, 16, 0);		/* (0 .. 255) */
+	case '\\': BIT (2, 9, 0);		/* (00 .. 11) */
  	}
        break;

@@ -284,6 +285,10 @@ decode_micromips_operand (const char *p)
  #define XPA	ASE_XPA
  #define XPAVZ	ASE_XPA_VIRT

+/* Global INValidate (GINV) support.  */
+#define GINV	ASE_GINV
+#define GINVVZ	ASE_GINV_VIRT
+
  const struct mips_opcode micromips_opcodes[] =
  {
  /* These instructions appear first so that the disassembler will find
@@ -1150,6 +1155,12 @@ const struct mips_opcode micromips_opcodes[] =
  {"xor",			"d,v,t",	0x00000310, 0xfc0007ff,	WR_1|RD_2|RD_3,		0,		I1,	 
0,	0 },
  {"xor",			"t,r,I",	0,    (int) M_XOR_I,	INSN_MACRO,		0,		I1,		0,	0 },
  {"xori",		"t,r,i",	0x70000000, 0xfc000000,	WR_1|RD_2,		0,		I1,		0,	0 },
+
+/* Global INValidate ASE */
+{"ginvi",		"s",		0x0000617c, 0xffe0ffff, RD_1,			0,		0,		GINV,	0 },
+{"ginvt",		"s,+\\",	0x0000717c, 0xffe0f9ff, RD_1,			0,		0,		GINV,	0 },
+{"ginvgt",		"s,+\\",	0x0000797c, 0xffe0f9ff, RD_1,			0,		0,		GINVVZ, 0 },
+
  /* microMIPS Enhanced VA Scheme */
  {"lbue",		"t,+j(b)",	0x60006000, 0xfc00fe00, WR_1|RD_3|LM,		0,		0,	 
EVA,	0 },
  {"lbue",		"t,A(b)",	0,    (int) M_LBUE_AB,	INSN_MACRO,		0,		0,		EVA,	0 },
diff --git a/opcodes/mips-dis.c b/opcodes/mips-dis.c
index 4519500..4eb8f00 100644
--- a/opcodes/mips-dis.c
+++ b/opcodes/mips-dis.c
@@ -563,7 +563,7 @@ const struct mips_arch_choice mips_arch_choices[] =
    { "mips32r6",	1, bfd_mach_mipsisa32r6, CPU_MIPS32R6,
      ISA_MIPS32R6,
      (ASE_EVA | ASE_MSA | ASE_VIRT | ASE_XPA | ASE_MCU | ASE_MT | ASE_DSP
-     | ASE_DSPR2 | ASE_DSPR3),
+     | ASE_DSPR2 | ASE_DSPR3 | ASE_GINV),
      mips_cp0_names_mips3264r2,
      mips_cp0sel_names_mips3264r2, ARRAY_SIZE 
(mips_cp0sel_names_mips3264r2),
      mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
@@ -602,7 +602,7 @@ const struct mips_arch_choice mips_arch_choices[] =
    { "mips64r6",	1, bfd_mach_mipsisa64r6, CPU_MIPS64R6,
      ISA_MIPS64R6,
      (ASE_EVA | ASE_MSA | ASE_MSA64 | ASE_XPA | ASE_VIRT | ASE_VIRT64
-     | ASE_MCU | ASE_MT | ASE_DSP | ASE_DSPR2 | ASE_DSPR3),
+     | ASE_MCU | ASE_MT | ASE_DSP | ASE_DSPR2 | ASE_DSPR3 | ASE_GINV),
      mips_cp0_names_mips3264r2,
      mips_cp0sel_names_mips3264r2, ARRAY_SIZE 
(mips_cp0sel_names_mips3264r2),
      mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
@@ -817,6 +817,8 @@ mips_calculate_combination_ases (unsigned long 
opcode_ases)

    if ((opcode_ases & (ASE_XPA | ASE_VIRT)) == (ASE_XPA | ASE_VIRT))
      combination_ases |= ASE_XPA_VIRT;
+  if ((opcode_ases & (ASE_GINV | ASE_VIRT)) == (ASE_GINV | ASE_VIRT))
+    combination_ases |= ASE_GINV_VIRT;
    if ((opcode_ases & (ASE_MIPS16E2 | ASE_MT)) == (ASE_MIPS16E2 | ASE_MT))
      combination_ases |= ASE_MIPS16E2_MT;
    return combination_ases;
@@ -900,6 +902,12 @@ set_default_mips_dis_options (struct 
disassemble_info *info)
  static bfd_boolean
  parse_mips_ase_option (const char *option)
  {
+  if (CONST_STRNEQ (option, "ginv"))
+    {
+      mips_ase |= ASE_GINV;
+      return TRUE;
+    }
+
    if (CONST_STRNEQ (option, "msa"))
      {
        mips_ase |= ASE_MSA;
diff --git a/opcodes/mips-opc.c b/opcodes/mips-opc.c
index 19fca40..ee8b3b7 100644
--- a/opcodes/mips-opc.c
+++ b/opcodes/mips-opc.c
@@ -139,6 +139,7 @@ decode_mips_operand (const char *p)
  	case '\'': BRANCH (26, 0, 2);
  	case '"': BRANCH (21, 0, 2);
  	case ';': SPECIAL (10, 16, SAME_RS_RT);
+	case '\\': BIT (2, 8, 0);		/* (00 .. 11) */
  	}
        break;

@@ -404,6 +405,10 @@ decode_mips_operand (const char *p)
  #define XPA     ASE_XPA
  #define XPAVZ	ASE_XPA_VIRT

+/* Global INValidate (GINV) support. */
+#define GINV	ASE_GINV
+#define GINVVZ	ASE_GINV_VIRT
+
  /* The order of overloaded instructions matters.  Label arguments and
     register arguments look the same. Instructions that can have either
     for arguments must apear in the correct order in this table for the
@@ -3275,6 +3280,10 @@ const struct mips_opcode mips_builtin_opcodes[] =
  {"jalrc",		"t",		0xf8000000, 0xffe0ffff, RD_1|NODS,		0,		I37,		0,	0 },
  {"jialc",		"t,j",		0xf8000000, 0xffe00000,	RD_1|NODS,		0,		I37,		0,	0 },

+{"ginvi",		"s",		0x7c00003d, 0xfc1fffff, RD_1,			0,		0,		GINV,	0 },
+{"ginvt",		"s,+\\",	0x7c0000bd, 0xfc1ffcff, RD_1,			0,		0,		GINV,	0 },
+{"ginvgt",		"s,+\\",	0x7c0000fd, 0xfc1ffcff, RD_1,			0,		0,		GINVVZ, 0 },
+
  {"cmp.af.s",		"D,S,T",	0x46800000, 0xffe0003f,	WR_1|RD_2|RD_3|FP_S,	0, 
	I37,		0,	0 },
  {"cmp.af.d",		"D,S,T",	0x46a00000, 0xffe0003f,	WR_1|RD_2|RD_3|FP_D,	0, 
	I37,		0,	0 },
  {"cmp.eq.s",		"D,S,T",	0x46800002, 0xffe0003f,	WR_1|RD_2|RD_3|FP_S,	0, 
	I37,		0,	0 },
-- 
2.9.5

^ permalink raw reply	[flat|nested] 5+ messages in thread

* RE: [PATCH][MIPS] Add Global INValidate instructions
  2017-11-27 22:46 [PATCH][MIPS] Add Global INValidate instructions Faraz Shahbazker
@ 2017-11-29 19:17 ` Faraz Shahbazker
  2018-01-09 19:00   ` Maciej W. Rozycki
  0 siblings, 1 reply; 5+ messages in thread
From: Faraz Shahbazker @ 2017-11-29 19:17 UTC (permalink / raw)
  To: binutils, Maciej Rozycki; +Cc: Matthew Fortune

Resubmitting with correct format.

Hi,

The following patch adds support for the Global INValidate (GINV)
instructions in Release 6 of the MIPS Architecture.  The changes are:
* New instruction GINVI, GINVT: enabled by option `-mginv'.
* New instruction GINVGT: enabled by `-mginv -mvirt'.
* Bit-17 in MIPS.abiflags is set when GINV extension is enabled.

The new ginv* instructions are described in Section 3.2 of the MIPS
Instruction Set v6.06
(https://www.mips.com/?do-download=the-mips32-instruction-set-v6-06)

This patch cannot be committed yet, since copyright assignment to FSF
from the new MIPS entity is still pending. Please review and approve
for a future commit.

Regards,
Faraz Shahbazker

ChangeLog:

bfd/
	* elfxx-mips.c (print_mips_ases): Add GINV extension.

binutils/
	* readelf.c (print_mips_ases) Add GINV extension.

gas/
	* config/tc-mips.c (options) <OPTION_GINV,  OPTION_NOGINV>:
	New.
	(md_longopts): Add -m[no-]ginv options.
	(mips_ases): Likewise.
	(mips_set_ase): Handle combination of VX and GINV extensions.
	(mips_convert_ase_flags): Add GINV extension.
	(md_show_usage): Add -m[no-]ginv options.
	* doc/as.texinfo: Add description for -m[no-]ginv.
	* doc/c-mips.texi: Likewise.

include/
	* elf/mips.h (AFL_ASE_GINV): New.
	(AFL_ASE_MASK): Update mask for all ASEs.

	* opcode/mips.h: Add comments for new operand format "+\".
	(ASE_GINV): New.
	(ASE_GINV_VIRT): Likewise.

opcodes/
	* mips-opc.c (decode_mips_operand) <+\>: New case.
	(GINV): New.
	(GINVVZ): Likewise.
	(mips_opcodes): Add instructions GINVI,  GINVT,  GINVGT.

	* micromips-opc.c (decode_micromips_operand) <+\>: New case.
	(GINV): New.
	(GINVVZ): Likewise.
	(micromips_opcodes): Add instructions GINVI,  GINVT,  GINVGT.

	* mips-dis.c (mips_arch_choices): Add GINV and VIRT_GINV ASEs
	to mips32r6 and mips64r6 descriptors.
	(mips_calculate_combination_ases): Set VIRT_GINV
	appropriately.
	(parse_mips_ase_option): Handle -mginv option.

gas/testsuite/
	* gas/mips/mips.exp: Add new tests.
	* gas/mips/ase-errors-1.s: Add new test cases.
	* gas/mips/ase-errors-2.s: Likewise.
	* gas/mips/ginv.s: New file.
	* gas/mips/ginv-error.s: Likewise.
	* gas/mips/ginv-virt-error.s: Likewise.
	* gas/mips/ginv.d: Likewise.
	* gas/mips/ginv-dis.d: Likewise.
	* gas/mips/ginv-virt.d: Likewise.
	* gas/mips/ginv-virt-dis.d: Likewise.
	* gas/mips/micromipsr@ginv.d: Likewise.
	* gas/mips/micromipsr@ginv-dis.d: Likewise.
	* gas/mips/micromipsr@ginv-virt.d: Likewise.
	* gas/mips/micromipsr@ginv-virt-dis.d: Likewise.
	* gas/mips/ase-errors-1.l: Update reference output.
	* gas/mips/ase-errors-2.l: Likewise.
	* gas/mips/ginv-error.l: New file.
	* gas/mips/ginv-virt-error.l: New file.
---
 bfd/elfxx-mips.c                                 |  2 ++
 binutils/readelf.c                               |  2 ++
 gas/config/tc-mips.c                             | 25 +++++++++++++++++++++++-
 gas/doc/as.texinfo                               |  7 +++++++
 gas/doc/c-mips.texi                              |  6 ++++++
 gas/testsuite/gas/mips/ase-errors-1.l            |  6 ++++++
 gas/testsuite/gas/mips/ase-errors-1.s            | 13 ++++++++++++
 gas/testsuite/gas/mips/ase-errors-2.l            |  6 ++++++
 gas/testsuite/gas/mips/ase-errors-2.s            | 13 ++++++++++++
 gas/testsuite/gas/mips/ginv-dis.d                | 15 ++++++++++++++
 gas/testsuite/gas/mips/ginv-error.l              |  2 ++
 gas/testsuite/gas/mips/ginv-error.s              |  8 ++++++++
 gas/testsuite/gas/mips/ginv-virt-dis.d           | 17 ++++++++++++++++
 gas/testsuite/gas/mips/ginv-virt-error.l         |  3 +++
 gas/testsuite/gas/mips/ginv-virt-error.s         | 10 ++++++++++
 gas/testsuite/gas/mips/ginv-virt.d               | 17 ++++++++++++++++
 gas/testsuite/gas/mips/ginv.d                    | 14 +++++++++++++
 gas/testsuite/gas/mips/ginv.s                    | 13 ++++++++++++
 gas/testsuite/gas/mips/micromips@ginv-dis.d      | 16 +++++++++++++++
 gas/testsuite/gas/mips/micromips@ginv-virt-dis.d | 17 ++++++++++++++++
 gas/testsuite/gas/mips/micromips@ginv-virt.d     | 17 ++++++++++++++++
 gas/testsuite/gas/mips/micromips@ginv.d          | 16 +++++++++++++++
 gas/testsuite/gas/mips/mips.exp                  |  8 ++++++++
 include/elf/mips.h                               |  3 ++-
 include/opcode/mips.h                            | 11 +++++++++++
 opcodes/micromips-opc.c                          | 11 +++++++++++
 opcodes/mips-dis.c                               | 12 ++++++++++--
 opcodes/mips-opc.c                               |  9 +++++++++
 28 files changed, 295 insertions(+), 4 deletions(-)
 create mode 100644 gas/testsuite/gas/mips/ginv-dis.d
 create mode 100644 gas/testsuite/gas/mips/ginv-error.l
 create mode 100644 gas/testsuite/gas/mips/ginv-error.s
 create mode 100644 gas/testsuite/gas/mips/ginv-virt-dis.d
 create mode 100644 gas/testsuite/gas/mips/ginv-virt-error.l
 create mode 100644 gas/testsuite/gas/mips/ginv-virt-error.s
 create mode 100644 gas/testsuite/gas/mips/ginv-virt.d
 create mode 100644 gas/testsuite/gas/mips/ginv.d
 create mode 100644 gas/testsuite/gas/mips/ginv.s
 create mode 100644 gas/testsuite/gas/mips/micromips@ginv-dis.d
 create mode 100644 gas/testsuite/gas/mips/micromips@ginv-virt-dis.d
 create mode 100644 gas/testsuite/gas/mips/micromips@ginv-virt.d
 create mode 100644 gas/testsuite/gas/mips/micromips@ginv.d

diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
index 8745e60..15fd6bb 100644
--- a/bfd/elfxx-mips.c
+++ b/bfd/elfxx-mips.c
@@ -15609,6 +15609,8 @@ print_mips_ases (FILE *file, unsigned int mask)
     fputs ("\n\tXPA ASE", file);
   if (mask & AFL_ASE_MIPS16E2)
     fputs ("\n\tMIPS16e2 ASE", file);
+  if (mask & AFL_ASE_GINV)
+    fputs ("\n\tGINV ASE", file);
   if (mask == 0)
     fprintf (file, "\n\t%s", _("None"));
   else if ((mask & ~AFL_ASE_MASK) != 0)
diff --git a/binutils/readelf.c b/binutils/readelf.c
index a1f43e6..7729501 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -15412,6 +15412,8 @@ print_mips_ases (unsigned int mask)
     fputs ("\n\tXPA ASE", stdout);
   if (mask & AFL_ASE_MIPS16E2)
     fputs ("\n\tMIPS16e2 ASE", stdout);
+  if (mask & AFL_ASE_GINV)
+    fputs ("\n\tGINV ASE", stdout);
   if (mask == 0)
     fprintf (stdout, "\n\t%s", _("None"));
   else if ((mask & ~AFL_ASE_MASK) != 0)
diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
index 040a373..f4b1e2d 100644
--- a/gas/config/tc-mips.c
+++ b/gas/config/tc-mips.c
@@ -1526,6 +1526,8 @@ enum options
     OPTION_NAN,
     OPTION_ODD_SPREG,
     OPTION_NO_ODD_SPREG,
+    OPTION_GINV,
+    OPTION_NO_GINV,
     OPTION_END_OF_ENUM
   };
 
@@ -1582,6 +1584,8 @@ struct option md_longopts[] =
   {"mno-xpa", no_argument, NULL, OPTION_NO_XPA},
   {"mmips16e2", no_argument, NULL, OPTION_MIPS16E2},
   {"mno-mips16e2", no_argument, NULL, OPTION_NO_MIPS16E2},
+  {"mginv", no_argument, NULL, OPTION_GINV},
+  {"mno-ginv", no_argument, NULL, OPTION_NO_GINV},
 
   /* Old-style architecture options.  Don't add more of these.  */
   {"m4650", no_argument, NULL, OPTION_M4650},
@@ -1769,6 +1773,11 @@ static const struct mips_ase mips_ases[] = {
     OPTION_MIPS16E2, OPTION_NO_MIPS16E2,
     2,  2, -1, -1,
     6 },
+
+  { "ginv", ASE_GINV, 0,
+    OPTION_GINV, OPTION_NO_GINV,
+    6,  6, 6, 6,
+    -1 },
 };
 
 /* The set of ASEs that require -mfp64.  */
@@ -2133,7 +2142,7 @@ mips_set_ase (const struct mips_ase *ase, struct mips_set_options *opts,
 
   /* Clear combination ASE flags, which need to be recalculated based on
      updated regular ASE settings.  */
-  opts->ase &= ~(ASE_MIPS16E2_MT | ASE_XPA_VIRT);
+  opts->ase &= ~(ASE_MIPS16E2_MT | ASE_XPA_VIRT | ASE_GINV_VIRT);
 
   if (enabled_p)
     opts->ase |= ase->flags;
@@ -2152,6 +2161,15 @@ mips_set_ase (const struct mips_ase *ase, struct mips_set_options *opts,
       mask |= ASE_MIPS16E2_MT;
     }
 
+  /* The Virtualization ASE has Global INValidate (GINV)
+     instructions which are only valid when both ASEs are enabled.
+     This sets the ASE_GINV_VIRT flag when both ASEs are present.  */
+  if ((opts->ase & (ASE_GINV | ASE_VIRT)) == (ASE_GINV | ASE_VIRT))
+    {
+      opts->ase |= ASE_GINV_VIRT;
+      mask |= ASE_GINV_VIRT;
+    }
+
   return mask;
 }
 
@@ -18977,6 +18995,8 @@ mips_convert_ase_flags (int ase)
     ext_ases |= AFL_ASE_XPA;
   if (ase & ASE_MIPS16E2)
     ext_ases |= file_ase_mips16 ? AFL_ASE_MIPS16E2 : 0;
+  if (ase & ASE_GINV)
+    ext_ases |= AFL_ASE_GINV;
 
   return ext_ases;
 }
@@ -19988,6 +20008,9 @@ MIPS options:\n\
 -mvirt			generate Virtualization instructions\n\
 -mno-virt		do not generate Virtualization instructions\n"));
   fprintf (stream, _("\
+-mginv			generate Global INValidate (GINV) instructions\n\
+-mno-ginv		do not generate Global INValidate instructions\n"));
+  fprintf (stream, _("\
 -minsn32		only generate 32-bit microMIPS instructions\n\
 -mno-insn32		generate all microMIPS instructions\n"));
   fprintf (stream, _("\
diff --git a/gas/doc/as.texinfo b/gas/doc/as.texinfo
index d37a1d6..700208f 100644
--- a/gas/doc/as.texinfo
+++ b/gas/doc/as.texinfo
@@ -432,6 +432,7 @@ gcc(1), ld(1), and the Info entries for @file{binutils} and @file{ld}.
    [@b{-mxpa}] [@b{-mno-xpa}]
    [@b{-mmt}] [@b{-mno-mt}]
    [@b{-mmcu}] [@b{-mno-mcu}]
+   [@b{-mginv}] [@b{-mno-ginv}]
    [@b{-minsn32}] [@b{-mno-insn32}]
    [@b{-mfix7000}] [@b{-mno-fix7000}]
    [@b{-mfix-rm7000}] [@b{-mno-fix-rm7000}]
@@ -1531,6 +1532,12 @@ Generate code for the MCU Application Specific Extension.
 This tells the assembler to accept MCU instructions.
 @samp{-mno-mcu} turns off this option.
 
+@item -mginv
+@itemx -mno-ginv
+Generate code for the Global INValidate (GINV) Application Specific
+Extension.  This tells the assembler to accept GINV instructions.
+@samp{-mno-ginv} turns off this option.
+
 @item -minsn32
 @itemx -mno-insn32
 Only use 32-bit instruction encodings when generating code for the
diff --git a/gas/doc/c-mips.texi b/gas/doc/c-mips.texi
index a430b0d..66b8f94 100644
--- a/gas/doc/c-mips.texi
+++ b/gas/doc/c-mips.texi
@@ -234,6 +234,12 @@ Generate code for the Virtualization Application Specific Extension.
 This tells the assembler to accept Virtualization instructions.
 @samp{-mno-virt} turns off this option.
 
+@item -mginv
+@itemx -mno-ginv
+Generate code for the Global INValidate (GINV) Application Specific
+Extension.  This tells the assembler to accept GINV instructions.
+@samp{-mno-ginv} turns off this option.
+
 @item -minsn32
 @itemx -mno-insn32
 Only use 32-bit instruction encodings when generating code for the
diff --git a/gas/testsuite/gas/mips/ase-errors-1.l b/gas/testsuite/gas/mips/ase-errors-1.l
index f989982..2c48f0b 100644
--- a/gas/testsuite/gas/mips/ase-errors-1.l
+++ b/gas/testsuite/gas/mips/ase-errors-1.l
@@ -40,3 +40,9 @@
 # ----------------------------------------------------------------------------
 .*:100: Warning: the `eva' extension requires MIPS32 revision 2 or greater
 .*:103: Error: opcode not supported.* `lbue \$4,16\(\$5\)'
+# ----------------------------------------------------------------------------
+.*:108: Error: invalid operands `ginvt \$f0,\$f1'
+.*:109: Warning: the `ginv' extension requires MIPS32 revision 6 or greater
+.*:114: Error: opcode not supported.* `ginvgt \$a1,3'
+.*:116: Error: opcode not supported.* `ginvi \$a0'
+# ----------------------------------------------------------------------------
diff --git a/gas/testsuite/gas/mips/ase-errors-1.s b/gas/testsuite/gas/mips/ase-errors-1.s
index c5201c3..82eee29 100644
--- a/gas/testsuite/gas/mips/ase-errors-1.s
+++ b/gas/testsuite/gas/mips/ase-errors-1.s
@@ -102,6 +102,19 @@
 	.set noeva
 	lbue $4,16($5)		# ERROR: eva not enabled
 
+	.set mips32r6
+	.set ginv		# OK
+	ginvi		$a0	# OK
+	ginvt 		$f0,$f1	# ERROR: Invalid operands
+	.set mips32r5		# ERROR: too low
+	ginvt		$a0,1	# OK
+	.set virt
+	ginvgt		$a0, 2	# OK
+	.set novirt
+	ginvgt		$a1, 3	# ERROR: virt not enabled
+	.set noginv
+	ginvi		$a0	# ERROR: crypto not enabled
+
 	# There should be no errors after this.
 	.set fp=32
 	.set mips1
diff --git a/gas/testsuite/gas/mips/ase-errors-2.l b/gas/testsuite/gas/mips/ase-errors-2.l
index 4c24690..b29c858 100644
--- a/gas/testsuite/gas/mips/ase-errors-2.l
+++ b/gas/testsuite/gas/mips/ase-errors-2.l
@@ -32,3 +32,9 @@
 # ----------------------------------------------------------------------------
 .*:84: Warning: the `eva' extension requires MIPS64 revision 2 or greater
 .*:87: Error: opcode not supported.* `lbue \$4,16\(\$5\)'
+# ----------------------------------------------------------------------------
+.*:92: Error: invalid operands `ginvt \$f0,\$f1'
+.*:93: Warning: the `ginv' extension requires MIPS64 revision 6 or greater
+.*:98: Error: opcode not supported.* `ginvgt \$a1,3'
+.*:100: Error: opcode not supported.* `ginvi \$a0'
+# ----------------------------------------------------------------------------
diff --git a/gas/testsuite/gas/mips/ase-errors-2.s b/gas/testsuite/gas/mips/ase-errors-2.s
index 4a17e4f..1312eb0 100644
--- a/gas/testsuite/gas/mips/ase-errors-2.s
+++ b/gas/testsuite/gas/mips/ase-errors-2.s
@@ -86,6 +86,19 @@
 	.set noeva
 	lbue $4,16($5)		# ERROR: eva not enabled
 
+	.set mips64r6
+	.set ginv		# OK
+	ginvi		$a0	# OK
+	ginvt 		$f0,$f1	# ERROR: Invalid operands
+	.set mips64r5		# ERROR: too low
+	ginvt		$a0,1	# OK
+	.set virt
+	ginvgt		$a0, 2	# OK
+	.set novirt
+	ginvgt		$a1, 3	# ERROR: virt not enabled
+	.set noginv
+	ginvi		$a0	# ERROR: crypto not enabled
+
 	# There should be no errors after this.
 	.set fp=32
 	.set mips4
diff --git a/gas/testsuite/gas/mips/ginv-dis.d b/gas/testsuite/gas/mips/ginv-dis.d
new file mode 100644
index 0000000..4738b5d
--- /dev/null
+++ b/gas/testsuite/gas/mips/ginv-dis.d
@@ -0,0 +1,15 @@
+#objdump: -Mginv -d --show-raw-insn
+#name: MIPS Global INValidate instructions disassembly
+#as: -mginv
+#source: ginv.s
+
+# Check MIPS Global INValidate instructions
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+00000000 <test>:
+   0:	7c40003d 	ginvi	v0
+   4:	7c6000bd 	ginvt	v1,0x0
+   8:	7c8001bd 	ginvt	a0,0x1
+	\.\.\.
diff --git a/gas/testsuite/gas/mips/ginv-error.l b/gas/testsuite/gas/mips/ginv-error.l
new file mode 100644
index 0000000..75e60e8
--- /dev/null
+++ b/gas/testsuite/gas/mips/ginv-error.l
@@ -0,0 +1,2 @@
+.*ginv-error.s: Assembler messages:
+.*ginv-error.s:3: Warning: the `ginv' extension requires MIPS32 revision 6 or greater
diff --git a/gas/testsuite/gas/mips/ginv-error.s b/gas/testsuite/gas/mips/ginv-error.s
new file mode 100644
index 0000000..1739be8
--- /dev/null
+++ b/gas/testsuite/gas/mips/ginv-error.s
@@ -0,0 +1,8 @@
+	.text
+test:
+	ginvi	$2
+	ginvt	$3,0
+	ginvt	$4,1
+
+	.align	2
+	.space	8
diff --git a/gas/testsuite/gas/mips/ginv-virt-dis.d b/gas/testsuite/gas/mips/ginv-virt-dis.d
new file mode 100644
index 0000000..bd07a3b
--- /dev/null
+++ b/gas/testsuite/gas/mips/ginv-virt-dis.d
@@ -0,0 +1,17 @@
+#objdump: -Mginv -Mvirt -d --show-raw-insn
+#name: MIPS GINV+VIRT disassembly
+#as: --defsym VX=1 -mginv -mvirt
+#source: ginv.s
+
+# Check MIPS Global INValidate Virtualization disassembly
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+00000000 <test>:
+   0:	7c40003d 	ginvi	v0
+   4:	7c6000bd 	ginvt	v1,0x0
+   8:	7c8001bd 	ginvt	a0,0x1
+   c:	7ca002fd 	ginvgt	a1,0x2
+  10:	7cc003fd 	ginvgt	a2,0x3
+	\.\.\.
diff --git a/gas/testsuite/gas/mips/ginv-virt-error.l b/gas/testsuite/gas/mips/ginv-virt-error.l
new file mode 100644
index 0000000..9fe7a30
--- /dev/null
+++ b/gas/testsuite/gas/mips/ginv-virt-error.l
@@ -0,0 +1,3 @@
+.*ginv-virt-error.s: Assembler messages:
+.*ginv-virt-error.s:6: Error: opcode not supported on this processor: mips32r6 \(mips32r6\) `ginvgt \$5,2'
+.*ginv-virt-error.s:7: Error: opcode not supported on this processor: mips32r6 \(mips32r6\) `ginvgt \$6,3'
diff --git a/gas/testsuite/gas/mips/ginv-virt-error.s b/gas/testsuite/gas/mips/ginv-virt-error.s
new file mode 100644
index 0000000..b9a201b
--- /dev/null
+++ b/gas/testsuite/gas/mips/ginv-virt-error.s
@@ -0,0 +1,10 @@
+	.text
+test:
+	ginvi	$2
+	ginvt	$3,0
+	ginvt	$4,1
+	ginvgt	$5,2
+	ginvgt	$6,3
+
+	.align	2
+	.space	8
diff --git a/gas/testsuite/gas/mips/ginv-virt.d b/gas/testsuite/gas/mips/ginv-virt.d
new file mode 100644
index 0000000..6390dc8
--- /dev/null
+++ b/gas/testsuite/gas/mips/ginv-virt.d
@@ -0,0 +1,17 @@
+#objdump: -d --show-raw-insn
+#name: MIPS Global INValidate Virtualization instructions
+#as: --defsym VX= -mginv -mvirt
+#source: ginv.s
+
+# Check MIPS Global INValidate Virtualization instructions
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+00000000 <test>:
+   0:	7c40003d 	ginvi	v0
+   4:	7c6000bd 	ginvt	v1,0x0
+   8:	7c8001bd 	ginvt	a0,0x1
+   c:	7ca002fd 	ginvgt	a1,0x2
+  10:	7cc003fd 	ginvgt	a2,0x3
+	\.\.\.
diff --git a/gas/testsuite/gas/mips/ginv.d b/gas/testsuite/gas/mips/ginv.d
new file mode 100644
index 0000000..0cc3c2d
--- /dev/null
+++ b/gas/testsuite/gas/mips/ginv.d
@@ -0,0 +1,14 @@
+#objdump: -d --show-raw-insn
+#name: MIPS Global INValidate instructions
+#as: -mginv
+
+# Check MIPS Global INValidate instructions
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+00000000 <test>:
+   0:	7c40003d 	ginvi	v0
+   4:	7c6000bd 	ginvt	v1,0x0
+   8:	7c8001bd 	ginvt	a0,0x1
+	\.\.\.
diff --git a/gas/testsuite/gas/mips/ginv.s b/gas/testsuite/gas/mips/ginv.s
new file mode 100644
index 0000000..e9f12ab
--- /dev/null
+++ b/gas/testsuite/gas/mips/ginv.s
@@ -0,0 +1,13 @@
+	.text
+test:
+	ginvi	$2
+	ginvt	$3,0
+	ginvt	$4,1
+
+	.ifdef VX
+	ginvgt	$5,2
+	ginvgt	$6,3
+	.endif
+
+	.align	2
+	.space	8
diff --git a/gas/testsuite/gas/mips/micromips@ginv-dis.d b/gas/testsuite/gas/mips/micromips@ginv-dis.d
new file mode 100644
index 0000000..e2e7000
--- /dev/null
+++ b/gas/testsuite/gas/mips/micromips@ginv-dis.d
@@ -0,0 +1,16 @@
+#objdump: -Mginv -d --show-raw-insn
+#name: MIPS microMIPS Global INValidate disassembly
+#as: -mginv
+#source: ginv.s
+
+# Check microMIPS Global INValidate disassembly
+
+.*: +file format .*mips.*
+
+
+Disassembly of section .text:
+00000000 <test>:
+   0:	0002 617c 	ginvi	v0
+   4:	0003 717c 	ginvt	v1,0x0
+   8:	0004 737c 	ginvt	a0,0x1
+	\.\.\.
diff --git a/gas/testsuite/gas/mips/micromips@ginv-virt-dis.d b/gas/testsuite/gas/mips/micromips@ginv-virt-dis.d
new file mode 100644
index 0000000..c0a4acb
--- /dev/null
+++ b/gas/testsuite/gas/mips/micromips@ginv-virt-dis.d
@@ -0,0 +1,17 @@
+#objdump: -mmips:isa32 -Mginv -Mvirt -d --show-raw-insn
+#name: MIPS microMIPS GINV+VIRT instruction disassembly
+#as: --defsym VX= -mginv -mvirt
+#source: ginv.s
+
+# Check microMIPS Global INValidate Virtualization disassembly
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+00000000 <test>:
+   0:	0002 617c 	ginvi	v0
+   4:	0003 717c 	ginvt	v1,0x0
+   8:	0004 737c 	ginvt	a0,0x1
+   c:	0005 7d7c 	ginvgt	a1,0x2
+  10:	0006 7f7c 	ginvgt	a2,0x3
+	\.\.\.
diff --git a/gas/testsuite/gas/mips/micromips@ginv-virt.d b/gas/testsuite/gas/mips/micromips@ginv-virt.d
new file mode 100644
index 0000000..08889fb
--- /dev/null
+++ b/gas/testsuite/gas/mips/micromips@ginv-virt.d
@@ -0,0 +1,17 @@
+#objdump: -d --show-raw-insn
+#name: MIPS microMIPS Global INValidate Virtualization instructions
+#as: --defsym VX= -mginv -mvirt
+#source: ginv.s
+
+# Check microMIPS Global INValidate Virtualization instructions
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+00000000 <test>:
+   0:	0002 617c 	ginvi	v0
+   4:	0003 717c 	ginvt	v1,0x0
+   8:	0004 737c 	ginvt	a0,0x1
+   c:	0005 7d7c 	ginvgt	a1,0x2
+  10:	0006 7f7c 	ginvgt	a2,0x3
+	\.\.\.
diff --git a/gas/testsuite/gas/mips/micromips@ginv.d b/gas/testsuite/gas/mips/micromips@ginv.d
new file mode 100644
index 0000000..e2e7000
--- /dev/null
+++ b/gas/testsuite/gas/mips/micromips@ginv.d
@@ -0,0 +1,16 @@
+#objdump: -Mginv -d --show-raw-insn
+#name: MIPS microMIPS Global INValidate disassembly
+#as: -mginv
+#source: ginv.s
+
+# Check microMIPS Global INValidate disassembly
+
+.*: +file format .*mips.*
+
+
+Disassembly of section .text:
+00000000 <test>:
+   0:	0002 617c 	ginvi	v0
+   4:	0003 717c 	ginvt	v1,0x0
+   8:	0004 737c 	ginvt	a0,0x1
+	\.\.\.
diff --git a/gas/testsuite/gas/mips/mips.exp b/gas/testsuite/gas/mips/mips.exp
index 94c4506..8e2dbc7 100644
--- a/gas/testsuite/gas/mips/mips.exp
+++ b/gas/testsuite/gas/mips/mips.exp
@@ -2050,4 +2050,12 @@ if { [istarget mips*-*-vxworks*] } {
 
     run_list_test_arches "r6-branch-constraints"  "-32" \
 			[mips_arch_list_matching mips32r6]
+
+    run_dump_test_arches "ginv" "" [mips_arch_list_matching mips32r6]
+    run_dump_test_arches "ginv-virt" "" [mips_arch_list_matching micromipsr6]
+    run_dump_test_arches "ginv-dis" "" [mips_arch_list_matching mips32r6]
+    run_dump_test_arches "ginv-virt-dis" "" \
+				[mips_arch_list_matching micromipsr6]
+    run_list_test "ginv-error" "-mips32 -mginv"
+    run_list_test "ginv-virt-error" "-mips32r6 -mginv"
 }
diff --git a/include/elf/mips.h b/include/elf/mips.h
index a4bea43..d98b312 100644
--- a/include/elf/mips.h
+++ b/include/elf/mips.h
@@ -1235,7 +1235,8 @@ extern void bfd_mips_elf_swap_abiflags_v0_out
 #define AFL_ASE_XPA          0x00001000 /* XPA ASE.  */
 #define AFL_ASE_DSPR3        0x00002000 /* DSP R3 ASE.  */
 #define AFL_ASE_MIPS16E2     0x00004000 /* MIPS16e2 ASE.  */
-#define AFL_ASE_MASK         0x00007fff /* All ASEs.  */
+#define AFL_ASE_GINV         0x00020000 /* GINV ASE.  */
+#define AFL_ASE_MASK         0x00027fff /* All ASEs.  */
 
 /* Values for the isa_ext word of an ABI flags structure.  */
 
diff --git a/include/opcode/mips.h b/include/opcode/mips.h
index ceae9ec..c163846 100644
--- a/include/opcode/mips.h
+++ b/include/opcode/mips.h
@@ -989,6 +989,9 @@ mips_opcode_32bit_p (const struct mips_opcode *mo)
    "-A" symbolic offset (-262144 .. 262143) << 2 at bit 0
    "-B" symbolic offset (-131072 .. 131071) << 3 at bit 0
 
+   GINV ASE usage:
+   "+\" 2 bit Global TLB invalidate type at bit 8
+
    Other:
    "()" parens surrounding optional value
    ","  separates operands
@@ -1294,6 +1297,11 @@ static const unsigned int mips_isa_table[] = {
 /* The Virtualization ASE has eXtended Physical Addressing (XPA)
    instructions which are only valid when both ASEs are enabled.  */
 #define ASE_XPA_VIRT		0x00020000
+/* Global INValidate Extension. */
+#define ASE_GINV		0x00800000
+/* The Virtualization ASE has Global INValidate extension instructions
+   which are only valid when both ASEs are enabled. */
+#define ASE_GINV_VIRT		0x01000000
 
 /* MIPS ISA defines, use instead of hardcoding ISA level.  */
 
@@ -2308,6 +2316,9 @@ extern const int bfd_mips16_num_opcodes;
    "+*" 5-bit register vector element index at bit 16
    "+|" 8-bit mask at bit 16
 
+   GINV ASE usage:
+   "+\" 2 bit Global TLB invalidate type at bit 8
+
    Other:
    "()" parens surrounding optional value
    ","  separates operands
diff --git a/opcodes/micromips-opc.c b/opcodes/micromips-opc.c
index d6234af..894c1f2 100644
--- a/opcodes/micromips-opc.c
+++ b/opcodes/micromips-opc.c
@@ -137,6 +137,7 @@ decode_micromips_operand (const char *p)
 	case '&': SPECIAL (0, 0, IMM_INDEX);
 	case '*': SPECIAL (5, 16, REG_INDEX);
 	case '|': BIT (8, 16, 0);		/* (0 .. 255) */
+	case '\\': BIT (2, 9, 0);		/* (00 .. 11) */
 	}
       break;
 
@@ -284,6 +285,10 @@ decode_micromips_operand (const char *p)
 #define XPA	ASE_XPA
 #define XPAVZ	ASE_XPA_VIRT
 
+/* Global INValidate (GINV) support.  */
+#define GINV	ASE_GINV
+#define GINVVZ	ASE_GINV_VIRT
+
 const struct mips_opcode micromips_opcodes[] =
 {
 /* These instructions appear first so that the disassembler will find
@@ -1150,6 +1155,12 @@ const struct mips_opcode micromips_opcodes[] =
 {"xor",			"d,v,t",	0x00000310, 0xfc0007ff,	WR_1|RD_2|RD_3,		0,		I1,		0,	0 },
 {"xor",			"t,r,I",	0,    (int) M_XOR_I,	INSN_MACRO,		0,		I1,		0,	0 },
 {"xori",		"t,r,i",	0x70000000, 0xfc000000,	WR_1|RD_2,		0,		I1,		0,	0 },
+
+/* Global INValidate ASE */
+{"ginvi",		"s",		0x0000617c, 0xffe0ffff, RD_1,			0,		0,		GINV,	0 },
+{"ginvt",		"s,+\\",	0x0000717c, 0xffe0f9ff, RD_1,			0,		0,		GINV,	0 },
+{"ginvgt",		"s,+\\",	0x0000797c, 0xffe0f9ff, RD_1,			0,		0,		GINVVZ, 0 },
+
 /* microMIPS Enhanced VA Scheme */
 {"lbue",		"t,+j(b)",	0x60006000, 0xfc00fe00, WR_1|RD_3|LM,		0,		0,		EVA,	0 },
 {"lbue",		"t,A(b)",	0,    (int) M_LBUE_AB,	INSN_MACRO,		0,		0,		EVA,	0 },
diff --git a/opcodes/mips-dis.c b/opcodes/mips-dis.c
index 4519500..4eb8f00 100644
--- a/opcodes/mips-dis.c
+++ b/opcodes/mips-dis.c
@@ -563,7 +563,7 @@ const struct mips_arch_choice mips_arch_choices[] =
   { "mips32r6",	1, bfd_mach_mipsisa32r6, CPU_MIPS32R6,
     ISA_MIPS32R6,
     (ASE_EVA | ASE_MSA | ASE_VIRT | ASE_XPA | ASE_MCU | ASE_MT | ASE_DSP
-     | ASE_DSPR2 | ASE_DSPR3),
+     | ASE_DSPR2 | ASE_DSPR3 | ASE_GINV),
     mips_cp0_names_mips3264r2,
     mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
     mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
@@ -602,7 +602,7 @@ const struct mips_arch_choice mips_arch_choices[] =
   { "mips64r6",	1, bfd_mach_mipsisa64r6, CPU_MIPS64R6,
     ISA_MIPS64R6,
     (ASE_EVA | ASE_MSA | ASE_MSA64 | ASE_XPA | ASE_VIRT | ASE_VIRT64
-     | ASE_MCU | ASE_MT | ASE_DSP | ASE_DSPR2 | ASE_DSPR3),
+     | ASE_MCU | ASE_MT | ASE_DSP | ASE_DSPR2 | ASE_DSPR3 | ASE_GINV),
     mips_cp0_names_mips3264r2,
     mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
     mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
@@ -817,6 +817,8 @@ mips_calculate_combination_ases (unsigned long opcode_ases)
 
   if ((opcode_ases & (ASE_XPA | ASE_VIRT)) == (ASE_XPA | ASE_VIRT))
     combination_ases |= ASE_XPA_VIRT;
+  if ((opcode_ases & (ASE_GINV | ASE_VIRT)) == (ASE_GINV | ASE_VIRT))
+    combination_ases |= ASE_GINV_VIRT;
   if ((opcode_ases & (ASE_MIPS16E2 | ASE_MT)) == (ASE_MIPS16E2 | ASE_MT))
     combination_ases |= ASE_MIPS16E2_MT;
   return combination_ases;
@@ -900,6 +902,12 @@ set_default_mips_dis_options (struct disassemble_info *info)
 static bfd_boolean
 parse_mips_ase_option (const char *option)
 {
+  if (CONST_STRNEQ (option, "ginv"))
+    {
+      mips_ase |= ASE_GINV;
+      return TRUE;
+    }
+
   if (CONST_STRNEQ (option, "msa"))
     {
       mips_ase |= ASE_MSA;
diff --git a/opcodes/mips-opc.c b/opcodes/mips-opc.c
index 19fca40..ee8b3b7 100644
--- a/opcodes/mips-opc.c
+++ b/opcodes/mips-opc.c
@@ -139,6 +139,7 @@ decode_mips_operand (const char *p)
 	case '\'': BRANCH (26, 0, 2);
 	case '"': BRANCH (21, 0, 2);
 	case ';': SPECIAL (10, 16, SAME_RS_RT);
+	case '\\': BIT (2, 8, 0);		/* (00 .. 11) */
 	}
       break;
 
@@ -404,6 +405,10 @@ decode_mips_operand (const char *p)
 #define XPA     ASE_XPA
 #define XPAVZ	ASE_XPA_VIRT
 
+/* Global INValidate (GINV) support. */
+#define GINV	ASE_GINV
+#define GINVVZ	ASE_GINV_VIRT
+
 /* The order of overloaded instructions matters.  Label arguments and
    register arguments look the same. Instructions that can have either
    for arguments must apear in the correct order in this table for the
@@ -3275,6 +3280,10 @@ const struct mips_opcode mips_builtin_opcodes[] =
 {"jalrc",		"t",		0xf8000000, 0xffe0ffff, RD_1|NODS,		0,		I37,		0,	0 },
 {"jialc",		"t,j",		0xf8000000, 0xffe00000,	RD_1|NODS,		0,		I37,		0,	0 },
 
+{"ginvi",		"s",		0x7c00003d, 0xfc1fffff, RD_1,			0,		0,		GINV,	0 },
+{"ginvt",		"s,+\\",	0x7c0000bd, 0xfc1ffcff, RD_1,			0,		0,		GINV,	0 },
+{"ginvgt",		"s,+\\",	0x7c0000fd, 0xfc1ffcff, RD_1,			0,		0,		GINVVZ, 0 },
+
 {"cmp.af.s",		"D,S,T",	0x46800000, 0xffe0003f,	WR_1|RD_2|RD_3|FP_S,	0,		I37,		0,	0 },
 {"cmp.af.d",		"D,S,T",	0x46a00000, 0xffe0003f,	WR_1|RD_2|RD_3|FP_D,	0,		I37,		0,	0 },
 {"cmp.eq.s",		"D,S,T",	0x46800002, 0xffe0003f,	WR_1|RD_2|RD_3|FP_S,	0,		I37,		0,	0 },
-- 
2.9.5

^ permalink raw reply	[flat|nested] 5+ messages in thread

* RE: [PATCH][MIPS] Add Global INValidate instructions
  2017-11-29 19:17 ` Faraz Shahbazker
@ 2018-01-09 19:00   ` Maciej W. Rozycki
  2018-06-13 19:30     ` [PATCH v3] MIPS: Add Global INValidate ASE support Faraz Shahbazker
  0 siblings, 1 reply; 5+ messages in thread
From: Maciej W. Rozycki @ 2018-01-09 19:00 UTC (permalink / raw)
  To: Faraz Shahbazker; +Cc: binutils, Matthew Fortune

Hi Faraz,

> Resubmitting with correct format.

 Thank you!

> The following patch adds support for the Global INValidate (GINV)
> instructions in Release 6 of the MIPS Architecture.  The changes are:
> * New instruction GINVI, GINVT: enabled by option `-mginv'.
> * New instruction GINVGT: enabled by `-mginv -mvirt'.
> * Bit-17 in MIPS.abiflags is set when GINV extension is enabled.
> 
> The new ginv* instructions are described in Section 3.2 of the MIPS
> Instruction Set v6.06
> (https://www.mips.com/?do-download=the-mips32-instruction-set-v6-06)

 Same as with the CRC patch -- please separate the commit description 
(which will be reviewed) from any extra discussion, and avoid volatile web 
links.

> This patch cannot be committed yet, since copyright assignment to FSF
> from the new MIPS entity is still pending. Please review and approve
> for a future commit.

 This change also triggers failures:

mips-sgi-irix6  +FAIL: MIPS Global INValidate instructions (mips32r6)
mips-sgi-irix6  +FAIL: MIPS Global INValidate instructions disassembly (mips32r6)
mips-sgi-irix6  +FAIL: mips ginv-error
mips-sgi-irix6  +FAIL: mips ginv-virt-error
mips64-freebsd  +FAIL: MIPS Global INValidate instructions (mips32r6)
mips64-freebsd  +FAIL: MIPS Global INValidate instructions disassembly (mips32r6)
mips64-freebsd  +FAIL: mips ginv-error
mips64-freebsd  +FAIL: mips ginv-virt-error
mips64-img-linux  +FAIL: MIPS Global INValidate instructions (mips32r6)
mips64-img-linux  +FAIL: MIPS Global INValidate instructions disassembly (mips32r6)
mips64-img-linux  +FAIL: mips ginv-error
mips64-img-linux  +FAIL: mips ginv-virt-error
mips64-linux  +FAIL: MIPS Global INValidate instructions (mips32r6)
mips64-linux  +FAIL: MIPS Global INValidate instructions disassembly (mips32r6)
mips64-linux  +FAIL: mips ginv-error
mips64-linux  +FAIL: mips ginv-virt-error
mips64-mti-linux  +FAIL: MIPS Global INValidate instructions (mips32r6)
mips64-mti-linux  +FAIL: MIPS Global INValidate instructions disassembly (mips32r6)
mips64-mti-linux  +FAIL: mips ginv-error
mips64-mti-linux  +FAIL: mips ginv-virt-error
mips64-openbsd  +FAIL: MIPS Global INValidate instructions (mips32r6)
mips64-openbsd  +FAIL: MIPS Global INValidate instructions (mips64r6)
mips64-openbsd  +FAIL: MIPS Global INValidate instructions disassembly (mips32r6)
mips64-openbsd  +FAIL: MIPS Global INValidate instructions disassembly (mips64r6)
mips64-openbsd  +FAIL: mips ginv-error
mips64-openbsd  +FAIL: mips ginv-virt-error
mips64el-freebsd  +FAIL: MIPS Global INValidate instructions (mips32r6)
mips64el-freebsd  +FAIL: MIPS Global INValidate instructions disassembly (mips32r6)
mips64el-freebsd  +FAIL: mips ginv-error
mips64el-freebsd  +FAIL: mips ginv-virt-error
mips64el-img-linux  +FAIL: MIPS Global INValidate instructions (mips32r6)
mips64el-img-linux  +FAIL: MIPS Global INValidate instructions disassembly (mips32r6)
mips64el-img-linux  +FAIL: mips ginv-error
mips64el-img-linux  +FAIL: mips ginv-virt-error
mips64el-linux  +FAIL: MIPS Global INValidate instructions (mips32r6)
mips64el-linux  +FAIL: MIPS Global INValidate instructions disassembly (mips32r6)
mips64el-linux  +FAIL: mips ginv-error
mips64el-linux  +FAIL: mips ginv-virt-error
mips64el-mti-linux  +FAIL: MIPS Global INValidate instructions (mips32r6)
mips64el-mti-linux  +FAIL: MIPS Global INValidate instructions disassembly (mips32r6)
mips64el-mti-linux  +FAIL: mips ginv-error
mips64el-mti-linux  +FAIL: mips ginv-virt-error
mips64el-openbsd  +FAIL: MIPS Global INValidate instructions (mips32r6)
mips64el-openbsd  +FAIL: MIPS Global INValidate instructions (mips64r6)
mips64el-openbsd  +FAIL: MIPS Global INValidate instructions disassembly (mips32r6)
mips64el-openbsd  +FAIL: MIPS Global INValidate instructions disassembly (mips64r6)
mips64el-openbsd  +FAIL: mips ginv-error
mips64el-openbsd  +FAIL: mips ginv-virt-error

-- please address them.

> diff --git a/include/elf/mips.h b/include/elf/mips.h
> index a4bea43..d98b312 100644
> --- a/include/elf/mips.h
> +++ b/include/elf/mips.h
> @@ -1235,7 +1235,8 @@ extern void bfd_mips_elf_swap_abiflags_v0_out
>  #define AFL_ASE_XPA          0x00001000 /* XPA ASE.  */
>  #define AFL_ASE_DSPR3        0x00002000 /* DSP R3 ASE.  */
>  #define AFL_ASE_MIPS16E2     0x00004000 /* MIPS16e2 ASE.  */
> -#define AFL_ASE_MASK         0x00007fff /* All ASEs.  */
> +#define AFL_ASE_GINV         0x00020000 /* GINV ASE.  */
> +#define AFL_ASE_MASK         0x00027fff /* All ASEs.  */

 There is a gap in bit allocation here, why?

> diff --git a/include/opcode/mips.h b/include/opcode/mips.h
> index ceae9ec..c163846 100644
> --- a/include/opcode/mips.h
> +++ b/include/opcode/mips.h
> @@ -989,6 +989,9 @@ mips_opcode_32bit_p (const struct mips_opcode *mo)
>     "-A" symbolic offset (-262144 .. 262143) << 2 at bit 0
>     "-B" symbolic offset (-131072 .. 131071) << 3 at bit 0
>  
> +   GINV ASE usage:
> +   "+\" 2 bit Global TLB invalidate type at bit 8

 You need to update the list of extension character sequences below 
accordingly.

> @@ -1294,6 +1297,11 @@ static const unsigned int mips_isa_table[] = {
>  /* The Virtualization ASE has eXtended Physical Addressing (XPA)
>     instructions which are only valid when both ASEs are enabled.  */
>  #define ASE_XPA_VIRT		0x00020000
> +/* Global INValidate Extension. */
> +#define ASE_GINV		0x00800000
> +/* The Virtualization ASE has Global INValidate extension instructions
> +   which are only valid when both ASEs are enabled. */
> +#define ASE_GINV_VIRT		0x01000000

 Again there is a gap in bit allocation here, why?

> @@ -2308,6 +2316,9 @@ extern const int bfd_mips16_num_opcodes;
>     "+*" 5-bit register vector element index at bit 16
>     "+|" 8-bit mask at bit 16
>  
> +   GINV ASE usage:
> +   "+\" 2 bit Global TLB invalidate type at bit 8

 And likewise you need to update the list of extension character sequences 
below accordingly.

 As discussed off-list this submission has similar formatting issues as 
your CRC change, so please address them accordingly when reposting.

  Maciej

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v3] MIPS: Add Global INValidate ASE support
  2018-01-09 19:00   ` Maciej W. Rozycki
@ 2018-06-13 19:30     ` Faraz Shahbazker
  2018-06-14 20:36       ` [committed v4] " Maciej W. Rozycki
  0 siblings, 1 reply; 5+ messages in thread
From: Faraz Shahbazker @ 2018-06-13 19:30 UTC (permalink / raw)
  To: Maciej Rozycki, binutils; +Cc: Matthew Fortune

Add support for the Global INValidate Application Specific Extension
for Release 6 of the MIPS Architecture.

[1] "MIPS Architecture for Programmers Volume II-A: The MIPS32
    Instruction Set Manual", Imagination Technologies Ltd., Document
    Number: MD00086, Revision 6.06, December 15, 2016, Section 3.2
    "Alphabetical List of Instructions", pp. 187-191

bfd/
	* elfxx-mips.c (print_mips_ases): Add GINV extension.

binutils/
	* readelf.c (print_mips_ases) Add GINV extension.

gas/
	* config/tc-mips.c (options): Add OPTION_GINV and OPTION_NO_GINV.
	(md_longopts): Likewise.
	(mips_ases): Define availability for GINV.
	(mips_convert_ase_flags): Map ASE_GINV to AFL_ASE_GINV.
	(md_show_usage): Add help for -mginv and -mno-ginv.
	* doc/as.texinfo: Document -mginv, -mno-ginv.
	* doc/c-mips.texi: Document -mginv, -mno-ginv, .set ginv and
	.set noginv.
	* testsuite/gas/mips/ase-errors-1.s: Add error checks for GINV
	ASE.
	* testsuite/gas/mips/ase-errors-2.s: Likewise.
	* testsuite/gas/mips/ase-errors-1.l: Likewise.
	* testsuite/gas/mips/ase-errors-2.l: Likewise.
	* testsuite/gas/mips/ginv.d: New test.
	* testsuite/gas/mips/ginv-err.d: New test.
	* testsuite/gas/mips/ginv-err.l: New test stderr output.
	* testsuite/gas/mips/ginv.s: New test source.
	* testsuite/gas/mips/ginv-err.s: New test source.
	* testsuite/gas/mips/mips.exp: Run the new tests.

include/
	* elf/mips.h (AFL_ASE_GINV, AFL_ASE_RESERVED1): New macros.
	(AFL_ASE_MASK): Update to include AFL_ASE_GINV.
	* opcode/mips.h: Comments describing new MIPS operand format "+\".
	(ASE_GINV): New macro.

opcodes/
	* mips-dis.c (mips_arch_choices): Add GINV to mips32r6 and
	mips64r6 descriptors.
	(parse_mips_ase_option): Handle -Mginv option.
	(print_mips_disassembler_options): Document -Mginv.
	* mips-opc.c (decode_mips_operand) <+\>: New operand format.
	(GINV): New macro.
	(mips_opcodes): Define ginvi and ginvt.

---
Updated patch v3, for review

The new ginv* instructions are described in Section 3.2 of the MIPS
Instruction Set v6.06:
  https://www.mips.com/?do-download=the-mips32-instruction-set-v6-06

Summary of changes:
* New instruction GINVI, GINVT: enabled by option `-mginv'.
* Bit-17 in MIPS.abiflags is set when GINV extension is enabled.

Significant changes w.r.t. patch v2:
* Remove unpublished variations of ginv* instructions (VZ, microMIPS).
* Print GINV in MIPS ASE flags.

Note that bit 16 (mask 0x10000) in the ases word of the MIPS ABI flags
structure is reserved by MIPS Tech for an ASE which is waiting to be
published.  Rather than keep an unspecified gap in the ases word, this
bit has been marked with the place-holder AFL_ASE_RESERVED1 for now.
---
 bfd/elfxx-mips.c                      |  2 ++
 binutils/readelf.c                    |  2 ++
 gas/NEWS                              |  2 ++
 gas/config/tc-mips.c                  | 14 ++++++++++++++
 gas/doc/as.texinfo                    |  7 +++++++
 gas/doc/c-mips.texi                   | 13 +++++++++++++
 gas/testsuite/gas/mips/ase-errors-1.l |  4 ++++
 gas/testsuite/gas/mips/ase-errors-1.s |  8 ++++++++
 gas/testsuite/gas/mips/ase-errors-2.l |  4 ++++
 gas/testsuite/gas/mips/ase-errors-2.s |  8 ++++++++
 gas/testsuite/gas/mips/ginv-err.d     |  3 +++
 gas/testsuite/gas/mips/ginv-err.l     |  4 ++++
 gas/testsuite/gas/mips/ginv-err.s     |  5 +++++
 gas/testsuite/gas/mips/ginv.d         | 18 ++++++++++++++++++
 gas/testsuite/gas/mips/ginv.s         |  9 +++++++++
 gas/testsuite/gas/mips/mips.exp       |  3 +++
 include/elf/mips.h                    |  4 +++-
 include/opcode/mips.h                 |  7 ++++++-
 opcodes/mips-dis.c                    | 14 ++++++++++++--
 opcodes/mips-opc.c                    |  8 ++++++++
 20 files changed, 135 insertions(+), 4 deletions(-)
 create mode 100644 gas/testsuite/gas/mips/ginv-err.d
 create mode 100644 gas/testsuite/gas/mips/ginv-err.l
 create mode 100644 gas/testsuite/gas/mips/ginv-err.s
 create mode 100644 gas/testsuite/gas/mips/ginv.d
 create mode 100644 gas/testsuite/gas/mips/ginv.s

diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
index 205faa6..5554698 100644
--- a/bfd/elfxx-mips.c
+++ b/bfd/elfxx-mips.c
@@ -15643,6 +15643,8 @@ print_mips_ases (FILE *file, unsigned int mask)
     fputs ("\n\tMIPS16e2 ASE", file);
   if (mask & AFL_ASE_CRC)
     fputs ("\n\tCRC ASE", file);
+  if (mask & AFL_ASE_GINV)
+    fputs ("\n\tGINV ASE", file);
   if (mask == 0)
     fprintf (file, "\n\t%s", _("None"));
   else if ((mask & ~AFL_ASE_MASK) != 0)
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 3af729f..9971307 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -15506,6 +15506,8 @@ print_mips_ases (unsigned int mask)
     fputs ("\n\tMIPS16e2 ASE", stdout);
   if (mask & AFL_ASE_CRC)
     fputs ("\n\tCRC ASE", stdout);
+  if (mask & AFL_ASE_GINV)
+    fputs ("\n\tGINV ASE", stdout);
   if (mask == 0)
     fprintf (stdout, "\n\t%s", _("None"));
   else if ((mask & ~AFL_ASE_MASK) != 0)
diff --git a/gas/NEWS b/gas/NEWS
index a50e264..9dfc845 100644
--- a/gas/NEWS
+++ b/gas/NEWS
@@ -1,5 +1,7 @@
 -*- text -*-
 
+* Add support for the MIPS Global INValidate (GINV) ASE.
+
 * Add support for the MIPS Cyclic Redudancy Check (CRC) ASE.
 
 * Add support for the Freescale S12Z architecture.
diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
index 7cadbb6..8dfc1f5 100644
--- a/gas/config/tc-mips.c
+++ b/gas/config/tc-mips.c
@@ -1527,6 +1527,8 @@ enum options
     OPTION_NAN,
     OPTION_ODD_SPREG,
     OPTION_NO_ODD_SPREG,
+    OPTION_GINV,
+    OPTION_NO_GINV,
     OPTION_END_OF_ENUM
   };
 
@@ -1585,6 +1587,8 @@ struct option md_longopts[] =
   {"mno-mips16e2", no_argument, NULL, OPTION_NO_MIPS16E2},
   {"mcrc", no_argument, NULL, OPTION_CRC},
   {"mno-crc", no_argument, NULL, OPTION_NO_CRC},
+  {"mginv", no_argument, NULL, OPTION_GINV},
+  {"mno-ginv", no_argument, NULL, OPTION_NO_GINV},
 
   /* Old-style architecture options.  Don't add more of these.  */
   {"m4650", no_argument, NULL, OPTION_M4650},
@@ -1777,6 +1781,11 @@ static const struct mips_ase mips_ases[] = {
     OPTION_CRC, OPTION_NO_CRC,
     6,  6, -1, -1,
     -1 },
+
+  { "ginv", ASE_GINV, 0,
+    OPTION_GINV, OPTION_NO_GINV,
+    6,  6, 6, 6,
+    -1 },
 };
 
 /* The set of ASEs that require -mfp64.  */
@@ -18987,6 +18996,8 @@ mips_convert_ase_flags (int ase)
     ext_ases |= file_ase_mips16 ? AFL_ASE_MIPS16E2 : 0;
   if (ase & ASE_CRC)
     ext_ases |= AFL_ASE_CRC;
+  if (ase & ASE_GINV)
+    ext_ases |= AFL_ASE_GINV;
 
   return ext_ases;
 }
@@ -20004,6 +20015,9 @@ MIPS options:\n\
 -mcrc			generate CRC instructions\n\
 -mno-crc		do not generate CRC instructions\n"));
   fprintf (stream, _("\
+-mginv			generate Global INValidate (GINV) instructions\n\
+-mno-ginv		do not generate Global INValidate instructions\n"));
+  fprintf (stream, _("\
 -minsn32		only generate 32-bit microMIPS instructions\n\
 -mno-insn32		generate all microMIPS instructions\n"));
   fprintf (stream, _("\
diff --git a/gas/doc/as.texinfo b/gas/doc/as.texinfo
index 1c40a1e..493049c 100644
--- a/gas/doc/as.texinfo
+++ b/gas/doc/as.texinfo
@@ -423,6 +423,7 @@ gcc(1), ld(1), and the Info entries for @file{binutils} and @file{ld}.
    [@b{-mmt}] [@b{-mno-mt}]
    [@b{-mmcu}] [@b{-mno-mcu}]
    [@b{-mcrc}] [@b{-mno-crc}]
+   [@b{-mginv}] [@b{-mno-ginv}]
    [@b{-minsn32}] [@b{-mno-insn32}]
    [@b{-mfix7000}] [@b{-mno-fix7000}]
    [@b{-mfix-rm7000}] [@b{-mno-fix-rm7000}]
@@ -1519,6 +1520,12 @@ Generate code for the MIPS cyclic redundancy check (CRC) Application
 Specific Extension.  This tells the assembler to accept CRC instructions.
 @samp{-mno-crc} turns off this option.
 
+@item -mginv
+@itemx -mno-ginv
+Generate code for the Global INValidate (GINV) Application Specific
+Extension.  This tells the assembler to accept GINV instructions.
+@samp{-mno-ginv} turns off this option.
+
 @item -minsn32
 @itemx -mno-insn32
 Only use 32-bit instruction encodings when generating code for the
diff --git a/gas/doc/c-mips.texi b/gas/doc/c-mips.texi
index 36997e9..9cbfaf2 100644
--- a/gas/doc/c-mips.texi
+++ b/gas/doc/c-mips.texi
@@ -240,6 +240,12 @@ Generate code for the cyclic redundancy check (CRC) Application Specific
 Extension.  This tells the assembler to accept CRC instructions.
 @samp{-mno-crc} turns off this option.
 
+@item -mginv
+@itemx -mno-ginv
+Generate code for the Global INValidate (GINV) Application Specific
+Extension.  This tells the assembler to accept GINV instructions.
+@samp{-mno-ginv} turns off this option.
+
 @item -minsn32
 @itemx -mno-insn32
 Only use 32-bit instruction encodings when generating code for the
@@ -1124,6 +1130,13 @@ The directive @code{.set crc} makes the assembler accept instructions
 from the CRC Extension from that point on in the assembly.  The
 @code{.set nocrc} directive prevents CRC instructions from being accepted.
 
+@cindex MIPS Global INValidate (GINV) instruction generation override
+@kindex @code{.set ginv}
+@kindex @code{.set noginv}
+The directive @code{.set ginv} makes the assembler accept instructions
+from the GINV Extension from that point on in the assembly.  The
+@code{.set noginv} directive prevents GINV instructions from being accepted.
+
 Traditional MIPS assemblers do not support these directives.
 
 @node MIPS Floating-Point
diff --git a/gas/testsuite/gas/mips/ase-errors-1.l b/gas/testsuite/gas/mips/ase-errors-1.l
index 7f7bba5..2c9fb9e 100644
--- a/gas/testsuite/gas/mips/ase-errors-1.l
+++ b/gas/testsuite/gas/mips/ase-errors-1.l
@@ -44,3 +44,7 @@
 .*:108: Error: opcode not supported.* `crc32d \$4,\$7,\$4'
 .*:109: Warning: the `crc' extension requires MIPS32 revision 6 or greater
 .*:112: Error: opcode not supported.* `crc32b \$4,\$7,\$4'
+# ----------------------------------------------------------------------------
+.*:117: Warning: the `ginv' extension requires MIPS32 revision 6 or greater
+.*:120: Error: opcode not supported.* `ginvi \$a0'
+# ----------------------------------------------------------------------------
diff --git a/gas/testsuite/gas/mips/ase-errors-1.s b/gas/testsuite/gas/mips/ase-errors-1.s
index 811f719..8b679a3 100644
--- a/gas/testsuite/gas/mips/ase-errors-1.s
+++ b/gas/testsuite/gas/mips/ase-errors-1.s
@@ -111,6 +111,14 @@
 	.set nocrc
 	crc32b $4,$7,$4		# ERROR: crc not enabled
 
+	.set mips32r6
+	.set ginv		# OK
+	ginvi $a0		# OK
+	.set mips32r5		# ERROR: too low
+	ginvt $a0, 1		# OK
+	.set noginv
+	ginvi $a0		# ERROR: ginv not enabled
+
 	# There should be no errors after this.
 	.set fp=32
 	.set mips1
diff --git a/gas/testsuite/gas/mips/ase-errors-2.l b/gas/testsuite/gas/mips/ase-errors-2.l
index 652c27c..6ac5163 100644
--- a/gas/testsuite/gas/mips/ase-errors-2.l
+++ b/gas/testsuite/gas/mips/ase-errors-2.l
@@ -36,3 +36,7 @@
 .*:93: Warning: the `crc' extension requires MIPS64 revision 6 or greater
 .*:97: Error: opcode not supported.* `crc32b \$4,\$7,\$4'
 .*:98: Error: opcode not supported.* `crc32d \$4,\$7,\$4'
+# ----------------------------------------------------------------------------
+.*:103: Warning: the `ginv' extension requires MIPS64 revision 6 or greater
+.*:106: Error: opcode not supported.* `ginvi \$a0'
+# ----------------------------------------------------------------------------
diff --git a/gas/testsuite/gas/mips/ase-errors-2.s b/gas/testsuite/gas/mips/ase-errors-2.s
index 7ef363e..2b31517 100644
--- a/gas/testsuite/gas/mips/ase-errors-2.s
+++ b/gas/testsuite/gas/mips/ase-errors-2.s
@@ -97,6 +97,14 @@
 	crc32b $4,$7,$4		# ERROR: crc not enabled
 	crc32d $4,$7,$4		# ERROR: crc not enabled
 
+	.set mips64r6
+	.set ginv		# OK
+	ginvi $a0		# OK
+	.set mips64r5		# ERROR: too low
+	ginvt $a0,1		# OK
+	.set noginv
+	ginvi $a0		# ERROR: ginv not enabled
+
 	# There should be no errors after this.
 	.set fp=32
 	.set mips4
diff --git a/gas/testsuite/gas/mips/ginv-err.d b/gas/testsuite/gas/mips/ginv-err.d
new file mode 100644
index 0000000..68c4096
--- /dev/null
+++ b/gas/testsuite/gas/mips/ginv-err.d
@@ -0,0 +1,3 @@
+#name: MIPS GINV instruction errors
+#as: -32 -mginv
+#error-output: ginv-err.l
diff --git a/gas/testsuite/gas/mips/ginv-err.l b/gas/testsuite/gas/mips/ginv-err.l
new file mode 100644
index 0000000..dbbb70c
--- /dev/null
+++ b/gas/testsuite/gas/mips/ginv-err.l
@@ -0,0 +1,4 @@
+.*: Assembler messages:
+.*:3: Error: invalid operands `ginvi 2'
+.*:4: Error: invalid operands `ginvt 3,3'
+.*:5: Error: operand 2 out of range `ginvt \$4,4'
diff --git a/gas/testsuite/gas/mips/ginv-err.s b/gas/testsuite/gas/mips/ginv-err.s
new file mode 100644
index 0000000..769fde3
--- /dev/null
+++ b/gas/testsuite/gas/mips/ginv-err.s
@@ -0,0 +1,5 @@
+	.text
+test:
+	ginvi	2
+	ginvt	3,3
+	ginvt	$4,4
diff --git a/gas/testsuite/gas/mips/ginv.d b/gas/testsuite/gas/mips/ginv.d
new file mode 100644
index 0000000..411bf6d
--- /dev/null
+++ b/gas/testsuite/gas/mips/ginv.d
@@ -0,0 +1,18 @@
+#objdump: -pdr --prefix-addresses --show-raw-insn
+#name: MIPS GINV
+#as: -mginv -32
+
+# Test GINV instructions
+
+.*: +file format .*mips.*
+#...
+ASEs:
+#...
+	GINV ASE
+#...
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> 7c40003d 	ginvi	v0
+[0-9a-f]+ <[^>]*> 7c6000bd 	ginvt	v1,0x0
+[0-9a-f]+ <[^>]*> 7c8001bd 	ginvt	a0,0x1
+	\.\.\.
diff --git a/gas/testsuite/gas/mips/ginv.s b/gas/testsuite/gas/mips/ginv.s
new file mode 100644
index 0000000..63cfb15
--- /dev/null
+++ b/gas/testsuite/gas/mips/ginv.s
@@ -0,0 +1,9 @@
+	.text
+test:
+	ginvi	$2
+	ginvt	$3,0
+	ginvt	$4,1
+
+# Force at least 8 (non-delay-slot) zero bytes, to make 'objdump' print ...
+	.align	2
+	.space	8
diff --git a/gas/testsuite/gas/mips/mips.exp b/gas/testsuite/gas/mips/mips.exp
index 47e923b..786168d 100644
--- a/gas/testsuite/gas/mips/mips.exp
+++ b/gas/testsuite/gas/mips/mips.exp
@@ -2061,4 +2061,7 @@ if { [istarget mips*-*-vxworks*] } {
     run_dump_test_arches "crc-err"	[mips_arch_list_matching mips32r6]
     run_dump_test_arches "crc64"	[mips_arch_list_matching mips64r6]
     run_dump_test_arches "crc64-err"	[mips_arch_list_matching mips64r6]
+
+    run_dump_test_arches "ginv"	[mips_arch_list_matching mips32r6]
+    run_dump_test_arches "ginv-err"	[mips_arch_list_matching mips32r6]
 }
diff --git a/include/elf/mips.h b/include/elf/mips.h
index d11b99f..4e2cde3 100644
--- a/include/elf/mips.h
+++ b/include/elf/mips.h
@@ -1236,7 +1236,9 @@ extern void bfd_mips_elf_swap_abiflags_v0_out
 #define AFL_ASE_DSPR3        0x00002000 /* DSP R3 ASE.  */
 #define AFL_ASE_MIPS16E2     0x00004000 /* MIPS16e2 ASE.  */
 #define AFL_ASE_CRC          0x00008000 /* CRC ASE.  */
-#define AFL_ASE_MASK         0x0000ffff /* All ASEs.  */
+#define AFL_ASE_RESERVED1    0x00010000 /* Reserved by MIPS Tech for WIP.  */
+#define AFL_ASE_GINV         0x00020000 /* GINV ASE.  */
+#define AFL_ASE_MASK         0x0002ffff /* All ASEs.  */
 
 /* Values for the isa_ext word of an ABI flags structure.  */
 
diff --git a/include/opcode/mips.h b/include/opcode/mips.h
index fcc70d5..1ab1780 100644
--- a/include/opcode/mips.h
+++ b/include/opcode/mips.h
@@ -989,6 +989,9 @@ mips_opcode_32bit_p (const struct mips_opcode *mo)
    "-A" symbolic offset (-262144 .. 262143) << 2 at bit 0
    "-B" symbolic offset (-131072 .. 131071) << 3 at bit 0
 
+   GINV ASE usage:
+   "+\" 2 bit Global TLB invalidate type at bit 8
+
    Other:
    "()" parens surrounding optional value
    ","  separates operands
@@ -1003,7 +1006,7 @@ mips_opcode_32bit_p (const struct mips_opcode *mo)
    Extension character sequences used so far ("+" followed by the
    following), for quick reference when adding more:
    "1234567890"
-   "~!@#$%^&*|:'";"
+   "~!@#$%^&*|:'";\"
    "ABCEFGHIJKLMNOPQRSTUVWXZ"
    "abcdefghijklmnopqrstuvwxyz"
 
@@ -1297,6 +1300,8 @@ static const unsigned int mips_isa_table[] = {
 /* Cyclic redundancy check (CRC) ASE.  */
 #define ASE_CRC			0x00040000
 #define ASE_CRC64		0x00080000
+/* Global INValidate Extension.  */
+#define ASE_GINV		0x00100000
 
 /* MIPS ISA defines, use instead of hardcoding ISA level.  */
 
diff --git a/opcodes/mips-dis.c b/opcodes/mips-dis.c
index 95a1937..9a5935b 100644
--- a/opcodes/mips-dis.c
+++ b/opcodes/mips-dis.c
@@ -563,7 +563,7 @@ const struct mips_arch_choice mips_arch_choices[] =
   { "mips32r6",	1, bfd_mach_mipsisa32r6, CPU_MIPS32R6,
     ISA_MIPS32R6,
     (ASE_EVA | ASE_MSA | ASE_VIRT | ASE_XPA | ASE_MCU | ASE_MT | ASE_DSP
-     | ASE_DSPR2 | ASE_DSPR3 | ASE_CRC),
+     | ASE_DSPR2 | ASE_DSPR3 | ASE_CRC | ASE_GINV),
     mips_cp0_names_mips3264r2,
     mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
     mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
@@ -603,7 +603,7 @@ const struct mips_arch_choice mips_arch_choices[] =
     ISA_MIPS64R6,
     (ASE_EVA | ASE_MSA | ASE_MSA64 | ASE_XPA | ASE_VIRT | ASE_VIRT64
      | ASE_MCU | ASE_MT | ASE_DSP | ASE_DSPR2 | ASE_DSPR3 | ASE_CRC
-     | ASE_CRC64),
+     | ASE_CRC64 | ASE_GINV),
     mips_cp0_names_mips3264r2,
     mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
     mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
@@ -901,6 +901,12 @@ set_default_mips_dis_options (struct disassemble_info *info)
 static bfd_boolean
 parse_mips_ase_option (const char *option)
 {
+  if (CONST_STRNEQ (option, "ginv"))
+    {
+      mips_ase |= ASE_GINV;
+      return TRUE;
+    }
+
   if (CONST_STRNEQ (option, "msa"))
     {
       mips_ase |= ASE_MSA;
@@ -2569,6 +2575,10 @@ with the -M switch (multiple options should be separated by commas):\n"));
                            ASE instructions.\n"));
 
   fprintf (stream, _("\n\
+  ginv                     Recognize the Global INValidate (GINV) ASe\n\
+                           instructions.\n"));
+
+  fprintf (stream, _("\n\
   gpr-names=ABI            Print GPR names according to specified ABI.\n\
                            Default: based on binary being disassembled.\n"));
 
diff --git a/opcodes/mips-opc.c b/opcodes/mips-opc.c
index d172801..34088b5 100644
--- a/opcodes/mips-opc.c
+++ b/opcodes/mips-opc.c
@@ -139,6 +139,7 @@ decode_mips_operand (const char *p)
 	case '\'': BRANCH (26, 0, 2);
 	case '"': BRANCH (21, 0, 2);
 	case ';': SPECIAL (10, 16, SAME_RS_RT);
+	case '\\': BIT (2, 8, 0);		/* (00 .. 11) */
 	}
       break;
 
@@ -408,6 +409,9 @@ decode_mips_operand (const char *p)
 #define CRC	ASE_CRC
 #define CRC64	ASE_CRC64
 
+/* Global INValidate (GINV) support.  */
+#define GINV	ASE_GINV
+
 /* The order of overloaded instructions matters.  Label arguments and
    register arguments look the same. Instructions that can have either
    for arguments must apear in the correct order in this table for the
@@ -3361,6 +3365,10 @@ const struct mips_opcode mips_builtin_opcodes[] =
 {"crc32cw",		"t,s,-d",	0x7c00018f, 0xfc00ffff, MOD_1|RD_2,		0,		0,		CRC,	0 },
 {"crc32cd",		"t,s,-d",	0x7c0001cf, 0xfc00ffff, MOD_1|RD_2,		0,		0,		CRC64,	0 },
 
+/* MIPS Global INValidate (GINV) ASE.  */
+{"ginvi",		"s",		0x7c00003d, 0xfc1fffff, RD_1,			0,		0,		GINV,	0 },
+{"ginvt",		"s,+\\",	0x7c0000bd, 0xfc1ffcff, RD_1,			0,		0,		GINV,	0 },
+
 /* No hazard protection on coprocessor instructions--they shouldn't
    change the state of the processor and if they do it's up to the
    user to put in nops as necessary.  These are at the end so that the
-- 
2.7.4

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [committed v4] MIPS: Add Global INValidate ASE support
  2018-06-13 19:30     ` [PATCH v3] MIPS: Add Global INValidate ASE support Faraz Shahbazker
@ 2018-06-14 20:36       ` Maciej W. Rozycki
  0 siblings, 0 replies; 5+ messages in thread
From: Maciej W. Rozycki @ 2018-06-14 20:36 UTC (permalink / raw)
  To: Faraz Shahbazker; +Cc: binutils, Matthew Fortune

Add support for the Global INValidate Application Specific Extension
for Release 6 of the MIPS Architecture.

[1] "MIPS Architecture for Programmers Volume II-A: The MIPS32
    Instruction Set Manual", Imagination Technologies Ltd., Document
    Number: MD00086, Revision 6.06, December 15, 2016, Section 3.2
    "Alphabetical List of Instructions", pp. 187-191

bfd/
	* elfxx-mips.c (print_mips_ases): Add GINV extension.

binutils/
	* readelf.c (print_mips_ases): Add GINV extension.

gas/
	* NEWS: Mention MIPS Global INValidate ASE support.
	* config/tc-mips.c (options): Add OPTION_GINV and OPTION_NO_GINV.
	(md_longopts): Likewise.
	(mips_ases): Define availability for GINV.
	(mips_convert_ase_flags): Map ASE_GINV to AFL_ASE_GINV.
	(md_show_usage): Add help for -mginv and -mno-ginv.
	* doc/as.texinfo: Document -mginv, -mno-ginv.
	* doc/c-mips.texi: Document -mginv, -mno-ginv, .set ginv and
	.set noginv.
	* testsuite/gas/mips/ase-errors-1.s: Add error checks for GINV
	ASE.
	* testsuite/gas/mips/ase-errors-2.s: Likewise.
	* testsuite/gas/mips/ase-errors-1.l: Likewise.
	* testsuite/gas/mips/ase-errors-2.l: Likewise.
	* testsuite/gas/mips/ginv.d: New test.
	* testsuite/gas/mips/ginv-err.d: New test.
	* testsuite/gas/mips/ginv-err.l: New test stderr output.
	* testsuite/gas/mips/ginv.s: New test source.
	* testsuite/gas/mips/ginv-err.s: New test source.
	* testsuite/gas/mips/mips.exp: Run the new tests.

include/
	* elf/mips.h (AFL_ASE_GINV, AFL_ASE_RESERVED1): New macros.
	(AFL_ASE_MASK): Update to include AFL_ASE_GINV.
	* opcode/mips.h: Document "+\" operand format.
	(ASE_GINV): New macro.

opcodes/
	* mips-dis.c (mips_arch_choices): Add GINV to mips32r6 and
	mips64r6 descriptors.
	(parse_mips_ase_option): Handle -Mginv option.
	(print_mips_disassembler_options): Document -Mginv.
	* mips-opc.c (decode_mips_operand) <+\>: New operand format.
	(GINV): New macro.
	(mips_opcodes): Define ginvi and ginvt.
---
Hi Faraz,

> Add support for the Global INValidate Application Specific Extension
> for Release 6 of the MIPS Architecture.

 I have fixed a small number of issues, most notably reordered the 
handling of the `-M ginv' in `parse_mips_ase_option' to match the order 
used elsewhere, and also a ChangeLog entry for the NEWS update in gas/ was 
missing (I also fixed the ChangeLog entry similarly for the CRC ASE 
support previously committed).  No issues in regression testing.  Here's 
the final version I have committed.

 Thank you for your contribution.

  Maciej
---
 bfd/elfxx-mips.c                      |    2 ++
 binutils/readelf.c                    |    2 ++
 gas/NEWS                              |    2 ++
 gas/config/tc-mips.c                  |   14 ++++++++++++++
 gas/doc/as.texinfo                    |    7 +++++++
 gas/doc/c-mips.texi                   |   13 +++++++++++++
 gas/testsuite/gas/mips/ase-errors-1.l |    4 ++++
 gas/testsuite/gas/mips/ase-errors-1.s |    8 ++++++++
 gas/testsuite/gas/mips/ase-errors-2.l |    4 ++++
 gas/testsuite/gas/mips/ase-errors-2.s |    8 ++++++++
 gas/testsuite/gas/mips/ginv-err.d     |    3 +++
 gas/testsuite/gas/mips/ginv-err.l     |    4 ++++
 gas/testsuite/gas/mips/ginv-err.s     |    5 +++++
 gas/testsuite/gas/mips/ginv.d         |   18 ++++++++++++++++++
 gas/testsuite/gas/mips/ginv.s         |    9 +++++++++
 gas/testsuite/gas/mips/mips.exp       |    3 +++
 include/elf/mips.h                    |    4 +++-
 include/opcode/mips.h                 |    7 ++++++-
 opcodes/mips-dis.c                    |   14 ++++++++++++--
 opcodes/mips-opc.c                    |    8 ++++++++
 20 files changed, 135 insertions(+), 4 deletions(-)
 create mode 100644 gas/testsuite/gas/mips/ginv-err.d
 create mode 100644 gas/testsuite/gas/mips/ginv-err.l
 create mode 100644 gas/testsuite/gas/mips/ginv-err.s
 create mode 100644 gas/testsuite/gas/mips/ginv.d
 create mode 100644 gas/testsuite/gas/mips/ginv.s

diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
index 6e2f6fe..f2c7e9e 100644
--- a/bfd/elfxx-mips.c
+++ b/bfd/elfxx-mips.c
@@ -15644,6 +15644,8 @@ print_mips_ases (FILE *file, unsigned int mask)
     fputs ("\n\tMIPS16e2 ASE", file);
   if (mask & AFL_ASE_CRC)
     fputs ("\n\tCRC ASE", file);
+  if (mask & AFL_ASE_GINV)
+    fputs ("\n\tGINV ASE", file);
   if (mask == 0)
     fprintf (file, "\n\t%s", _("None"));
   else if ((mask & ~AFL_ASE_MASK) != 0)
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 2188b25..c713e7f 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -15511,6 +15511,8 @@ print_mips_ases (unsigned int mask)
     fputs ("\n\tMIPS16e2 ASE", stdout);
   if (mask & AFL_ASE_CRC)
     fputs ("\n\tCRC ASE", stdout);
+  if (mask & AFL_ASE_GINV)
+    fputs ("\n\tGINV ASE", stdout);
   if (mask == 0)
     fprintf (stdout, "\n\t%s", _("None"));
   else if ((mask & ~AFL_ASE_MASK) != 0)
diff --git a/gas/NEWS b/gas/NEWS
index a50e264..9dfc845 100644
--- a/gas/NEWS
+++ b/gas/NEWS
@@ -1,5 +1,7 @@
 -*- text -*-
 
+* Add support for the MIPS Global INValidate (GINV) ASE.
+
 * Add support for the MIPS Cyclic Redudancy Check (CRC) ASE.
 
 * Add support for the Freescale S12Z architecture.
diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
index 7cadbb6..8dfc1f5 100644
--- a/gas/config/tc-mips.c
+++ b/gas/config/tc-mips.c
@@ -1527,6 +1527,8 @@ enum options
     OPTION_NAN,
     OPTION_ODD_SPREG,
     OPTION_NO_ODD_SPREG,
+    OPTION_GINV,
+    OPTION_NO_GINV,
     OPTION_END_OF_ENUM
   };
 
@@ -1585,6 +1587,8 @@ struct option md_longopts[] =
   {"mno-mips16e2", no_argument, NULL, OPTION_NO_MIPS16E2},
   {"mcrc", no_argument, NULL, OPTION_CRC},
   {"mno-crc", no_argument, NULL, OPTION_NO_CRC},
+  {"mginv", no_argument, NULL, OPTION_GINV},
+  {"mno-ginv", no_argument, NULL, OPTION_NO_GINV},
 
   /* Old-style architecture options.  Don't add more of these.  */
   {"m4650", no_argument, NULL, OPTION_M4650},
@@ -1777,6 +1781,11 @@ static const struct mips_ase mips_ases[] = {
     OPTION_CRC, OPTION_NO_CRC,
     6,  6, -1, -1,
     -1 },
+
+  { "ginv", ASE_GINV, 0,
+    OPTION_GINV, OPTION_NO_GINV,
+    6,  6, 6, 6,
+    -1 },
 };
 
 /* The set of ASEs that require -mfp64.  */
@@ -18987,6 +18996,8 @@ mips_convert_ase_flags (int ase)
     ext_ases |= file_ase_mips16 ? AFL_ASE_MIPS16E2 : 0;
   if (ase & ASE_CRC)
     ext_ases |= AFL_ASE_CRC;
+  if (ase & ASE_GINV)
+    ext_ases |= AFL_ASE_GINV;
 
   return ext_ases;
 }
@@ -20004,6 +20015,9 @@ MIPS options:\n\
 -mcrc			generate CRC instructions\n\
 -mno-crc		do not generate CRC instructions\n"));
   fprintf (stream, _("\
+-mginv			generate Global INValidate (GINV) instructions\n\
+-mno-ginv		do not generate Global INValidate instructions\n"));
+  fprintf (stream, _("\
 -minsn32		only generate 32-bit microMIPS instructions\n\
 -mno-insn32		generate all microMIPS instructions\n"));
   fprintf (stream, _("\
diff --git a/gas/doc/as.texinfo b/gas/doc/as.texinfo
index 1c40a1e..493049c 100644
--- a/gas/doc/as.texinfo
+++ b/gas/doc/as.texinfo
@@ -423,6 +423,7 @@ gcc(1), ld(1), and the Info entries for @file{binutils} and @file{ld}.
    [@b{-mmt}] [@b{-mno-mt}]
    [@b{-mmcu}] [@b{-mno-mcu}]
    [@b{-mcrc}] [@b{-mno-crc}]
+   [@b{-mginv}] [@b{-mno-ginv}]
    [@b{-minsn32}] [@b{-mno-insn32}]
    [@b{-mfix7000}] [@b{-mno-fix7000}]
    [@b{-mfix-rm7000}] [@b{-mno-fix-rm7000}]
@@ -1519,6 +1520,12 @@ Generate code for the MIPS cyclic redundancy check (CRC) Application
 Specific Extension.  This tells the assembler to accept CRC instructions.
 @samp{-mno-crc} turns off this option.
 
+@item -mginv
+@itemx -mno-ginv
+Generate code for the Global INValidate (GINV) Application Specific
+Extension.  This tells the assembler to accept GINV instructions.
+@samp{-mno-ginv} turns off this option.
+
 @item -minsn32
 @itemx -mno-insn32
 Only use 32-bit instruction encodings when generating code for the
diff --git a/gas/doc/c-mips.texi b/gas/doc/c-mips.texi
index 36997e9..9cbfaf2 100644
--- a/gas/doc/c-mips.texi
+++ b/gas/doc/c-mips.texi
@@ -240,6 +240,12 @@ Generate code for the cyclic redundancy check (CRC) Application Specific
 Extension.  This tells the assembler to accept CRC instructions.
 @samp{-mno-crc} turns off this option.
 
+@item -mginv
+@itemx -mno-ginv
+Generate code for the Global INValidate (GINV) Application Specific
+Extension.  This tells the assembler to accept GINV instructions.
+@samp{-mno-ginv} turns off this option.
+
 @item -minsn32
 @itemx -mno-insn32
 Only use 32-bit instruction encodings when generating code for the
@@ -1124,6 +1130,13 @@ The directive @code{.set crc} makes the assembler accept instructions
 from the CRC Extension from that point on in the assembly.  The
 @code{.set nocrc} directive prevents CRC instructions from being accepted.
 
+@cindex MIPS Global INValidate (GINV) instruction generation override
+@kindex @code{.set ginv}
+@kindex @code{.set noginv}
+The directive @code{.set ginv} makes the assembler accept instructions
+from the GINV Extension from that point on in the assembly.  The
+@code{.set noginv} directive prevents GINV instructions from being accepted.
+
 Traditional MIPS assemblers do not support these directives.
 
 @node MIPS Floating-Point
diff --git a/gas/testsuite/gas/mips/ase-errors-1.l b/gas/testsuite/gas/mips/ase-errors-1.l
index 7f7bba5..2c9fb9e 100644
--- a/gas/testsuite/gas/mips/ase-errors-1.l
+++ b/gas/testsuite/gas/mips/ase-errors-1.l
@@ -44,3 +44,7 @@
 .*:108: Error: opcode not supported.* `crc32d \$4,\$7,\$4'
 .*:109: Warning: the `crc' extension requires MIPS32 revision 6 or greater
 .*:112: Error: opcode not supported.* `crc32b \$4,\$7,\$4'
+# ----------------------------------------------------------------------------
+.*:117: Warning: the `ginv' extension requires MIPS32 revision 6 or greater
+.*:120: Error: opcode not supported.* `ginvi \$a0'
+# ----------------------------------------------------------------------------
diff --git a/gas/testsuite/gas/mips/ase-errors-1.s b/gas/testsuite/gas/mips/ase-errors-1.s
index 811f719..8b679a3 100644
--- a/gas/testsuite/gas/mips/ase-errors-1.s
+++ b/gas/testsuite/gas/mips/ase-errors-1.s
@@ -111,6 +111,14 @@
 	.set nocrc
 	crc32b $4,$7,$4		# ERROR: crc not enabled
 
+	.set mips32r6
+	.set ginv		# OK
+	ginvi $a0		# OK
+	.set mips32r5		# ERROR: too low
+	ginvt $a0, 1		# OK
+	.set noginv
+	ginvi $a0		# ERROR: ginv not enabled
+
 	# There should be no errors after this.
 	.set fp=32
 	.set mips1
diff --git a/gas/testsuite/gas/mips/ase-errors-2.l b/gas/testsuite/gas/mips/ase-errors-2.l
index 652c27c..6ac5163 100644
--- a/gas/testsuite/gas/mips/ase-errors-2.l
+++ b/gas/testsuite/gas/mips/ase-errors-2.l
@@ -36,3 +36,7 @@
 .*:93: Warning: the `crc' extension requires MIPS64 revision 6 or greater
 .*:97: Error: opcode not supported.* `crc32b \$4,\$7,\$4'
 .*:98: Error: opcode not supported.* `crc32d \$4,\$7,\$4'
+# ----------------------------------------------------------------------------
+.*:103: Warning: the `ginv' extension requires MIPS64 revision 6 or greater
+.*:106: Error: opcode not supported.* `ginvi \$a0'
+# ----------------------------------------------------------------------------
diff --git a/gas/testsuite/gas/mips/ase-errors-2.s b/gas/testsuite/gas/mips/ase-errors-2.s
index 7ef363e..2b31517 100644
--- a/gas/testsuite/gas/mips/ase-errors-2.s
+++ b/gas/testsuite/gas/mips/ase-errors-2.s
@@ -97,6 +97,14 @@
 	crc32b $4,$7,$4		# ERROR: crc not enabled
 	crc32d $4,$7,$4		# ERROR: crc not enabled
 
+	.set mips64r6
+	.set ginv		# OK
+	ginvi $a0		# OK
+	.set mips64r5		# ERROR: too low
+	ginvt $a0,1		# OK
+	.set noginv
+	ginvi $a0		# ERROR: ginv not enabled
+
 	# There should be no errors after this.
 	.set fp=32
 	.set mips4
diff --git a/gas/testsuite/gas/mips/ginv-err.d b/gas/testsuite/gas/mips/ginv-err.d
new file mode 100644
index 0000000..68c4096
--- /dev/null
+++ b/gas/testsuite/gas/mips/ginv-err.d
@@ -0,0 +1,3 @@
+#name: MIPS GINV instruction errors
+#as: -32 -mginv
+#error-output: ginv-err.l
diff --git a/gas/testsuite/gas/mips/ginv-err.l b/gas/testsuite/gas/mips/ginv-err.l
new file mode 100644
index 0000000..dbbb70c
--- /dev/null
+++ b/gas/testsuite/gas/mips/ginv-err.l
@@ -0,0 +1,4 @@
+.*: Assembler messages:
+.*:3: Error: invalid operands `ginvi 2'
+.*:4: Error: invalid operands `ginvt 3,3'
+.*:5: Error: operand 2 out of range `ginvt \$4,4'
diff --git a/gas/testsuite/gas/mips/ginv-err.s b/gas/testsuite/gas/mips/ginv-err.s
new file mode 100644
index 0000000..769fde3
--- /dev/null
+++ b/gas/testsuite/gas/mips/ginv-err.s
@@ -0,0 +1,5 @@
+	.text
+test:
+	ginvi	2
+	ginvt	3,3
+	ginvt	$4,4
diff --git a/gas/testsuite/gas/mips/ginv.d b/gas/testsuite/gas/mips/ginv.d
new file mode 100644
index 0000000..1cb2955
--- /dev/null
+++ b/gas/testsuite/gas/mips/ginv.d
@@ -0,0 +1,18 @@
+#objdump: -pdr --prefix-addresses --show-raw-insn
+#name: MIPS GINV
+#as: -mginv -32
+
+# Test GINV instructions.
+
+.*: +file format .*mips.*
+#...
+ASEs:
+#...
+	GINV ASE
+#...
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> 7c40003d 	ginvi	v0
+[0-9a-f]+ <[^>]*> 7c6000bd 	ginvt	v1,0x0
+[0-9a-f]+ <[^>]*> 7c8001bd 	ginvt	a0,0x1
+	\.\.\.
diff --git a/gas/testsuite/gas/mips/ginv.s b/gas/testsuite/gas/mips/ginv.s
new file mode 100644
index 0000000..63cfb15
--- /dev/null
+++ b/gas/testsuite/gas/mips/ginv.s
@@ -0,0 +1,9 @@
+	.text
+test:
+	ginvi	$2
+	ginvt	$3,0
+	ginvt	$4,1
+
+# Force at least 8 (non-delay-slot) zero bytes, to make 'objdump' print ...
+	.align	2
+	.space	8
diff --git a/gas/testsuite/gas/mips/mips.exp b/gas/testsuite/gas/mips/mips.exp
index 47e923b..786168d 100644
--- a/gas/testsuite/gas/mips/mips.exp
+++ b/gas/testsuite/gas/mips/mips.exp
@@ -2061,4 +2061,7 @@ if { [istarget mips*-*-vxworks*] } {
     run_dump_test_arches "crc-err"	[mips_arch_list_matching mips32r6]
     run_dump_test_arches "crc64"	[mips_arch_list_matching mips64r6]
     run_dump_test_arches "crc64-err"	[mips_arch_list_matching mips64r6]
+
+    run_dump_test_arches "ginv"	[mips_arch_list_matching mips32r6]
+    run_dump_test_arches "ginv-err"	[mips_arch_list_matching mips32r6]
 }
diff --git a/include/elf/mips.h b/include/elf/mips.h
index d11b99f..4e2cde3 100644
--- a/include/elf/mips.h
+++ b/include/elf/mips.h
@@ -1236,7 +1236,9 @@ extern void bfd_mips_elf_swap_abiflags_v0_out
 #define AFL_ASE_DSPR3        0x00002000 /* DSP R3 ASE.  */
 #define AFL_ASE_MIPS16E2     0x00004000 /* MIPS16e2 ASE.  */
 #define AFL_ASE_CRC          0x00008000 /* CRC ASE.  */
-#define AFL_ASE_MASK         0x0000ffff /* All ASEs.  */
+#define AFL_ASE_RESERVED1    0x00010000 /* Reserved by MIPS Tech for WIP.  */
+#define AFL_ASE_GINV         0x00020000 /* GINV ASE.  */
+#define AFL_ASE_MASK         0x0002ffff /* All ASEs.  */
 
 /* Values for the isa_ext word of an ABI flags structure.  */
 
diff --git a/include/opcode/mips.h b/include/opcode/mips.h
index fcc70d5..1ab1780 100644
--- a/include/opcode/mips.h
+++ b/include/opcode/mips.h
@@ -989,6 +989,9 @@ mips_opcode_32bit_p (const struct mips_opcode *mo)
    "-A" symbolic offset (-262144 .. 262143) << 2 at bit 0
    "-B" symbolic offset (-131072 .. 131071) << 3 at bit 0
 
+   GINV ASE usage:
+   "+\" 2 bit Global TLB invalidate type at bit 8
+
    Other:
    "()" parens surrounding optional value
    ","  separates operands
@@ -1003,7 +1006,7 @@ mips_opcode_32bit_p (const struct mips_opcode *mo)
    Extension character sequences used so far ("+" followed by the
    following), for quick reference when adding more:
    "1234567890"
-   "~!@#$%^&*|:'";"
+   "~!@#$%^&*|:'";\"
    "ABCEFGHIJKLMNOPQRSTUVWXZ"
    "abcdefghijklmnopqrstuvwxyz"
 
@@ -1297,6 +1300,8 @@ static const unsigned int mips_isa_table[] = {
 /* Cyclic redundancy check (CRC) ASE.  */
 #define ASE_CRC			0x00040000
 #define ASE_CRC64		0x00080000
+/* Global INValidate Extension.  */
+#define ASE_GINV		0x00100000
 
 /* MIPS ISA defines, use instead of hardcoding ISA level.  */
 
diff --git a/opcodes/mips-dis.c b/opcodes/mips-dis.c
index 95a1937..aeb8d7e 100644
--- a/opcodes/mips-dis.c
+++ b/opcodes/mips-dis.c
@@ -563,7 +563,7 @@ const struct mips_arch_choice mips_arch_choices[] =
   { "mips32r6",	1, bfd_mach_mipsisa32r6, CPU_MIPS32R6,
     ISA_MIPS32R6,
     (ASE_EVA | ASE_MSA | ASE_VIRT | ASE_XPA | ASE_MCU | ASE_MT | ASE_DSP
-     | ASE_DSPR2 | ASE_DSPR3 | ASE_CRC),
+     | ASE_DSPR2 | ASE_DSPR3 | ASE_CRC | ASE_GINV),
     mips_cp0_names_mips3264r2,
     mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
     mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
@@ -603,7 +603,7 @@ const struct mips_arch_choice mips_arch_choices[] =
     ISA_MIPS64R6,
     (ASE_EVA | ASE_MSA | ASE_MSA64 | ASE_XPA | ASE_VIRT | ASE_VIRT64
      | ASE_MCU | ASE_MT | ASE_DSP | ASE_DSPR2 | ASE_DSPR3 | ASE_CRC
-     | ASE_CRC64),
+     | ASE_CRC64 | ASE_GINV),
     mips_cp0_names_mips3264r2,
     mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
     mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
@@ -929,6 +929,12 @@ parse_mips_ase_option (const char *option)
       return TRUE;
     }
 
+  if (CONST_STRNEQ (option, "ginv"))
+    {
+      mips_ase |= ASE_GINV;
+      return TRUE;
+    }
+
   return FALSE;
 }
 
@@ -2569,6 +2575,10 @@ with the -M switch (multiple options should be separated by commas):\n"));
                            ASE instructions.\n"));
 
   fprintf (stream, _("\n\
+  ginv                     Recognize the Global INValidate (GINV) ASe\n\
+                           instructions.\n"));
+
+  fprintf (stream, _("\n\
   gpr-names=ABI            Print GPR names according to specified ABI.\n\
                            Default: based on binary being disassembled.\n"));
 
diff --git a/opcodes/mips-opc.c b/opcodes/mips-opc.c
index d172801..1cbcbc6 100644
--- a/opcodes/mips-opc.c
+++ b/opcodes/mips-opc.c
@@ -139,6 +139,7 @@ decode_mips_operand (const char *p)
 	case '\'': BRANCH (26, 0, 2);
 	case '"': BRANCH (21, 0, 2);
 	case ';': SPECIAL (10, 16, SAME_RS_RT);
+	case '\\': BIT (2, 8, 0);		/* (0 .. 3) */
 	}
       break;
 
@@ -408,6 +409,9 @@ decode_mips_operand (const char *p)
 #define CRC	ASE_CRC
 #define CRC64	ASE_CRC64
 
+/* Global INValidate (GINV) support.  */
+#define GINV	ASE_GINV
+
 /* The order of overloaded instructions matters.  Label arguments and
    register arguments look the same. Instructions that can have either
    for arguments must apear in the correct order in this table for the
@@ -3361,6 +3365,10 @@ const struct mips_opcode mips_builtin_opcodes[] =
 {"crc32cw",		"t,s,-d",	0x7c00018f, 0xfc00ffff, MOD_1|RD_2,		0,		0,		CRC,	0 },
 {"crc32cd",		"t,s,-d",	0x7c0001cf, 0xfc00ffff, MOD_1|RD_2,		0,		0,		CRC64,	0 },
 
+/* MIPS Global INValidate (GINV) ASE.  */
+{"ginvi",		"s",		0x7c00003d, 0xfc1fffff, RD_1,			0,		0,		GINV,	0 },
+{"ginvt",		"s,+\\",	0x7c0000bd, 0xfc1ffcff, RD_1,			0,		0,		GINV,	0 },
+
 /* No hazard protection on coprocessor instructions--they shouldn't
    change the state of the processor and if they do it's up to the
    user to put in nops as necessary.  These are at the end so that the
-- 
1.7.2.5

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2018-06-14 20:36 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-27 22:46 [PATCH][MIPS] Add Global INValidate instructions Faraz Shahbazker
2017-11-29 19:17 ` Faraz Shahbazker
2018-01-09 19:00   ` Maciej W. Rozycki
2018-06-13 19:30     ` [PATCH v3] MIPS: Add Global INValidate ASE support Faraz Shahbazker
2018-06-14 20:36       ` [committed v4] " Maciej W. Rozycki

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).