[PATCH 4/4] opcodes,gas: sparc: fix rdasr,wrasr,rdpr,wrpr,rdhpr,wrhpr insns.

Jose E. Marchesi jose.marchesi@oracle.com
Wed Jun 15 15:53:00 GMT 2016


This patch fixes and expands the definition of the read/write
instructions for ancillary-state, privileged and hyperprivileged
registers in opcodes.

It also adds support for three new v9m hyperprivileged registers:
%hmcdper, %hmcddfr and %hva_mask_nz.

Finally, the patch expands existing tests (and adds several new ones) in
order to cover all the read/write instructions in all its variants.

opcodes/ChangeLog:

2016-06-15  Jose E. Marchesi  <jose.marchesi@oracle.com>

	* sparc-opc.c (rdasr): New macro.
	(wrasr): Likewise.
	(rdpr): Likewise.
	(wrpr): Likewise.
	(rdhpr): Likewise.
	(wrhpr): Likewise.
	(sparc_opcodes): Use the macros above to fix and expand the
	definition of read/write instructions from/to
	asr/privileged/hyperprivileged instructions.
	* sparc-dis.c (v9_hpriv_reg_names): Add %hmcdper, %hmcddfr and
	%hva_mask_nz.  Prefer softint_set and softint_clear over
	set_softint and clear_softint.
	(print_insn_sparc): Support %ver in Rd.

gas/ChangeLog:

2016-06-15  Jose E. Marchesi  <jose.marchesi@oracle.com>

	* config/tc-sparc.c (hpriv_reg_table): Add registers %hmcdper,
	%hmcddfr and %hva_mask_nz.
	(sparc_ip): New handling of asr/privileged/hyperprivileged
	registers, adapted to the new form of the sparc opcodes table.
	* testsuite/gas/sparc/rdasr.s: New file.
	* testsuite/gas/sparc/rdasr.d: Likewise.
	* testsuite/gas/sparc/wrasr.s: Likewise.
	* testsuite/gas/sparc/wrasr.d: Likewise.
	* testsuite/gas/sparc/sparc.exp (sparc_elf_setup): Add rdasr and
	wrasr tests.
	* testsuite/gas/sparc/rdpr.d: Use -Av9m, as some privileged
	registers require it.
	* testsuite/gas/sparc/wrpr.s: Complete to cover all privileged
	registers and write instruction modalities.
	* testsuite/gas/sparc/wrpr.d: Likewise.
	* testsuite/gas/sparc/rdhpr.s: Likewise for hyperprivileged
	registers.
	* testsuite/gas/sparc/rdhpr.d: Likewise.
	* testsuite/gas/sparc/wrhpr.s: Likewise.
	* testsuite/gas/sparc/wrhpr.d: Likewise.
---
 gas/ChangeLog                     |  23 +++++
 gas/config/tc-sparc.c             |  51 ++++++-----
 gas/testsuite/gas/sparc/rdasr.d   |  18 ++++
 gas/testsuite/gas/sparc/rdasr.s   |  11 +++
 gas/testsuite/gas/sparc/rdhpr.d   |   5 +-
 gas/testsuite/gas/sparc/rdhpr.s   |   3 +
 gas/testsuite/gas/sparc/rdpr.d    |   2 +-
 gas/testsuite/gas/sparc/sparc.exp |   2 +
 gas/testsuite/gas/sparc/wrasr.d   |  48 +++++++++++
 gas/testsuite/gas/sparc/wrasr.s   |  41 +++++++++
 gas/testsuite/gas/sparc/wrhpr.d   |  59 +++++++++++--
 gas/testsuite/gas/sparc/wrhpr.s   |  57 +++++++++++--
 gas/testsuite/gas/sparc/wrpr.d    | 114 +++++++++++++++++++++----
 gas/testsuite/gas/sparc/wrpr.s    | 110 ++++++++++++++++++++----
 opcodes/ChangeLog                 |  16 ++++
 opcodes/sparc-dis.c               |   8 +-
 opcodes/sparc-opc.c               | 174 +++++++++++++++++++++++++++-----------
 17 files changed, 613 insertions(+), 129 deletions(-)
 create mode 100644 gas/testsuite/gas/sparc/rdasr.d
 create mode 100644 gas/testsuite/gas/sparc/rdasr.s
 create mode 100644 gas/testsuite/gas/sparc/wrasr.d
 create mode 100644 gas/testsuite/gas/sparc/wrasr.s

diff --git a/gas/ChangeLog b/gas/ChangeLog
index ca1b096..79f42ed 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,5 +1,28 @@
 2016-06-15  Jose E. Marchesi  <jose.marchesi@oracle.com>
 
+	* config/tc-sparc.c (hpriv_reg_table): Add registers %hmcdper,
+	%hmcddfr and %hva_mask_nz.
+	(sparc_ip): New handling of asr/privileged/hyperprivileged
+	registers, adapted to the new form of the sparc opcodes table.
+	* testsuite/gas/sparc/rdasr.s: New file.
+	* testsuite/gas/sparc/rdasr.d: Likewise.
+	* testsuite/gas/sparc/wrasr.s: Likewise.
+	* testsuite/gas/sparc/wrasr.d: Likewise.
+	* testsuite/gas/sparc/sparc.exp (sparc_elf_setup): Add rdasr and
+	wrasr tests.
+	* testsuite/gas/sparc/rdpr.d: Use -Av9m, as some privileged
+	registers require it.
+	* testsuite/gas/sparc/wrpr.s: Complete to cover all privileged
+	registers and write instruction modalities.
+	* testsuite/gas/sparc/wrpr.d: Likewise.
+	* testsuite/gas/sparc/rdhpr.s: Likewise for hyperprivileged
+	registers.
+	* testsuite/gas/sparc/rdhpr.d: Likewise.
+	* testsuite/gas/sparc/wrhpr.s: Likewise.
+	* testsuite/gas/sparc/wrhpr.d: Likewise.
+
+2016-06-15  Jose E. Marchesi  <jose.marchesi@oracle.com>
+
 	* config/tc-sparc.c (sparc_arch_table): adjust the GAS
 	architectures to use the right opcode architecture.
 	(sparc_md_end): Handle v9{c,d,e,v,m}.
diff --git a/gas/config/tc-sparc.c b/gas/config/tc-sparc.c
index 283e132..163a216 100644
--- a/gas/config/tc-sparc.c
+++ b/gas/config/tc-sparc.c
@@ -817,6 +817,9 @@ struct priv_reg_entry hpriv_reg_table[] =
   {"hintp", 3},
   {"htba", 5},
   {"hver", 6},
+  {"hmcdper", 23},
+  {"hmcddfr", 24},
+  {"hva_mask_nz", 27},
   {"hstick_offset", 28},
   {"hstick_enable", 29},
   {"hstick_cmpr", 31},
@@ -1907,10 +1910,13 @@ sparc_ip (char *str, const struct sparc_opcode **pinsn)
 		      error_message = _(": unrecognizable privileged register");
 		      goto error;
 		    }
-		  if (*args == '?')
-		    opcode |= (p->regnum << 14);
-		  else
-		    opcode |= (p->regnum << 25);
+                  
+                  if (((opcode >> (*args == '?' ? 14 : 25)) & 0x1f) != (unsigned) p->regnum)
+                    {
+                      error_message = _(": unrecognizable privileged register");
+                      goto error;
+                    }
+
 		  s += len;
 		  continue;
 		}
@@ -1942,11 +1948,14 @@ sparc_ip (char *str, const struct sparc_opcode **pinsn)
 		      error_message = _(": unrecognizable hyperprivileged register");
 		      goto error;
 		    }
-		  if (*args == '$')
-		    opcode |= (p->regnum << 14);
-		  else
-		    opcode |= (p->regnum << 25);
-		  s += len;
+
+                  if (((opcode >> (*args == '$' ? 14 : 25)) & 0x1f) != (unsigned) p->regnum)
+                    {
+                      error_message = _(": unrecognizable hyperprivileged register");
+                      goto error;
+                    }
+
+                  s += len;
 		  continue;
 		}
 	      else
@@ -1977,23 +1986,13 @@ sparc_ip (char *str, const struct sparc_opcode **pinsn)
 		      error_message = _(": unrecognizable ancillary state register");
 		      goto error;
 		    }
-		  if (*args == '/' && (p->regnum == 20 || p->regnum == 21))
-		    {
-		      error_message = _(": rd on write only ancillary state register");
-		      goto error;
-		    }
-		  if (p->regnum >= 24
-		      && (insn->architecture
-			  & SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9A)))
-		    {
-		      /* %sys_tick and %sys_tick_cmpr are v9bnotv9a */
-		      error_message = _(": unrecognizable v9a ancillary state register");
-		      goto error;
-		    }
-		  if (*args == '/')
-		    opcode |= (p->regnum << 14);
-		  else
-		    opcode |= (p->regnum << 25);
+
+                  if (((opcode >> (*args == '/' ? 14 : 25)) & 0x1f) != (unsigned) p->regnum)
+                     {
+                       error_message = _(": unrecognizable ancillary state register");
+                       goto error;
+                     }
+
 		  s += len;
 		  continue;
 		}
diff --git a/gas/testsuite/gas/sparc/rdasr.d b/gas/testsuite/gas/sparc/rdasr.d
new file mode 100644
index 0000000..6acd9c8
--- /dev/null
+++ b/gas/testsuite/gas/sparc/rdasr.d
@@ -0,0 +1,18 @@
+#as: -64 -Av9m
+#objdump: -dr
+#name: sparc64 rdasr
+
+.*: +file format .*sparc.*
+
+Disassembly of section .text:
+
+0+ <.text>:
+   0:	81 44 00 00 	rd  %pcr, %g0
+   4:	83 44 40 00 	rd  %pic, %g1
+   8:	85 44 80 00 	rd  %dcr, %g2
+   c:	87 44 c0 00 	rd  %gsr, %g3
+  10:	89 45 80 00 	rd  %softint, %g4
+  14:	8b 45 c0 00 	rd  %tick_cmpr, %g5
+  18:	8b 46 00 00 	rd  %stick, %g5
+  1c:	89 46 40 00 	rd  %stick_cmpr, %g4
+  20:	8d 46 80 00 	rd  %cfr, %g6
diff --git a/gas/testsuite/gas/sparc/rdasr.s b/gas/testsuite/gas/sparc/rdasr.s
new file mode 100644
index 0000000..8499764
--- /dev/null
+++ b/gas/testsuite/gas/sparc/rdasr.s
@@ -0,0 +1,11 @@
+# Test rdasr
+	.text
+	rd %pcr,%g0
+	rd %pic,%g1
+	rd %dcr,%g2
+	rd %gsr,%g3
+	rd %softint,%g4
+	rd %tick_cmpr,%g5
+	rd %sys_tick,%g5
+	rd %sys_tick_cmpr,%g4
+	rd %cfr,%g6
diff --git a/gas/testsuite/gas/sparc/rdhpr.d b/gas/testsuite/gas/sparc/rdhpr.d
index 7a12ad3..81995d5 100644
--- a/gas/testsuite/gas/sparc/rdhpr.d
+++ b/gas/testsuite/gas/sparc/rdhpr.d
@@ -1,4 +1,4 @@
-#as: -64 -Av9
+#as: -64 -Av9m
 #objdump: -dr
 #name: sparc64 rdhpr
 
@@ -15,3 +15,6 @@ Disassembly of section .text:
   14:	8d 4f 00 00 	rdhpr  %hstick_offset, %g6
   18:	8b 4f 40 00 	rdhpr  %hstick_enable, %g5
   1c:	89 4f c0 00 	rdhpr  %hstick_cmpr, %g4
+  20:	8d 4d c0 00 	rdhpr  %hmcdper, %g6
+  24:	8b 4e 00 00 	rdhpr  %hmcddfr, %g5
+  28:	89 4e c0 00 	rdhpr  %hva_mask_nz, %g4
diff --git a/gas/testsuite/gas/sparc/rdhpr.s b/gas/testsuite/gas/sparc/rdhpr.s
index 8f669c7..c4cf2de 100644
--- a/gas/testsuite/gas/sparc/rdhpr.s
+++ b/gas/testsuite/gas/sparc/rdhpr.s
@@ -8,3 +8,6 @@
 	rdhpr %hstick_offset,%g6
 	rdhpr %hstick_enable,%g5
 	rdhpr %hstick_cmpr,%g4
+	rdhpr %hmcdper,%g6
+	rdhpr %hmcddfr,%g5
+	rdhpr %hva_mask_nz,%g4
diff --git a/gas/testsuite/gas/sparc/rdpr.d b/gas/testsuite/gas/sparc/rdpr.d
index 58ec2ef..d9e9972 100644
--- a/gas/testsuite/gas/sparc/rdpr.d
+++ b/gas/testsuite/gas/sparc/rdpr.d
@@ -1,4 +1,4 @@
-#as: -64 -Av9
+#as: -64 -Av9m
 #objdump: -dr
 #name: sparc64 rdpr
 
diff --git a/gas/testsuite/gas/sparc/sparc.exp b/gas/testsuite/gas/sparc/sparc.exp
index 3e7cc4c..0a6a494 100644
--- a/gas/testsuite/gas/sparc/sparc.exp
+++ b/gas/testsuite/gas/sparc/sparc.exp
@@ -56,8 +56,10 @@ if [istarget sparc*-*-*] {
 	run_dump_test "prefetch"
 	run_dump_test "set64"
 	run_dump_test "synth64"
+        run_dump_test "rdasr"
 	run_dump_test "rdpr"
 	run_dump_test "rdhpr"
+        run_dump_test "wrasr"
 	run_dump_test "wrpr"
 	run_dump_test "wrhpr"
 	run_dump_test "window"
diff --git a/gas/testsuite/gas/sparc/wrasr.d b/gas/testsuite/gas/sparc/wrasr.d
new file mode 100644
index 0000000..93729c7
--- /dev/null
+++ b/gas/testsuite/gas/sparc/wrasr.d
@@ -0,0 +1,48 @@
+#as: -64 -Av9m
+#objdump: -dr
+#name: sparc64 wrasr
+
+.*: +file format .*sparc.*
+
+Disassembly of section .text:
+
+0+ <.text>:
+   0:	a1 80 40 02 	wr  %g1, %g2, %pcr
+   4:	a1 80 62 9a 	wr  %g1, 0x29a, %pcr
+   8:	a1 80 62 9a 	wr  %g1, 0x29a, %pcr
+   c:	a3 80 40 02 	wr  %g1, %g2, %pic
+  10:	a3 80 62 9a 	wr  %g1, 0x29a, %pic
+  14:	a3 80 62 9a 	wr  %g1, 0x29a, %pic
+  18:	a5 80 40 02 	wr  %g1, %g2, %dcr
+  1c:	a5 80 62 9a 	wr  %g1, 0x29a, %dcr
+  20:	a5 80 62 9a 	wr  %g1, 0x29a, %dcr
+  24:	a7 80 40 02 	wr  %g1, %g2, %gsr
+  28:	a7 80 62 9a 	wr  %g1, 0x29a, %gsr
+  2c:	a7 80 62 9a 	wr  %g1, 0x29a, %gsr
+  30:	a9 80 40 02 	wr  %g1, %g2, %softint_set
+  34:	a9 80 62 9a 	wr  %g1, 0x29a, %softint_set
+  38:	a9 80 62 9a 	wr  %g1, 0x29a, %softint_set
+  3c:	ab 80 40 02 	wr  %g1, %g2, %softint_clear
+  40:	ab 80 62 9a 	wr  %g1, 0x29a, %softint_clear
+  44:	ab 80 62 9a 	wr  %g1, 0x29a, %softint_clear
+  48:	ad 80 40 02 	wr  %g1, %g2, %softint
+  4c:	ad 80 62 9a 	wr  %g1, 0x29a, %softint
+  50:	ad 80 62 9a 	wr  %g1, 0x29a, %softint
+  54:	af 80 40 02 	wr  %g1, %g2, %tick_cmpr
+  58:	af 80 62 9a 	wr  %g1, 0x29a, %tick_cmpr
+  5c:	af 80 62 9a 	wr  %g1, 0x29a, %tick_cmpr
+  60:	b1 80 40 02 	wr  %g1, %g2, %stick
+  64:	b1 80 62 9a 	wr  %g1, 0x29a, %stick
+  68:	b1 80 62 9a 	wr  %g1, 0x29a, %stick
+  6c:	b3 80 40 02 	wr  %g1, %g2, %stick_cmpr
+  70:	b3 80 62 9a 	wr  %g1, 0x29a, %stick_cmpr
+  74:	b3 80 62 9a 	wr  %g1, 0x29a, %stick_cmpr
+  78:	b5 80 40 02 	wr  %g1, %g2, %cfr
+  7c:	b5 80 62 9a 	wr  %g1, 0x29a, %cfr
+  80:	b5 80 62 9a 	wr  %g1, 0x29a, %cfr
+  84:	b7 80 40 02 	wr  %g1, %g2, %pause
+  88:	b7 80 62 9a 	wr  %g1, 0x29a, %pause
+  8c:	b7 80 62 9a 	wr  %g1, 0x29a, %pause
+  90:	b9 80 40 02 	wr  %g1, %g2, %mwait
+  94:	b9 80 62 9a 	wr  %g1, 0x29a, %mwait
+  98:	b9 80 62 9a 	wr  %g1, 0x29a, %mwait
diff --git a/gas/testsuite/gas/sparc/wrasr.s b/gas/testsuite/gas/sparc/wrasr.s
new file mode 100644
index 0000000..07f858e
--- /dev/null
+++ b/gas/testsuite/gas/sparc/wrasr.s
@@ -0,0 +1,41 @@
+# Test wrasr
+	.text
+	wr %g1, %g2, %pcr
+	wr %g1, 666, %pcr
+	wr 666, %g1, %pcr
+	wr %g1, %g2, %pic
+	wr %g1, 666, %pic
+	wr 666, %g1, %pic
+	wr %g1, %g2, %dcr
+	wr %g1, 666, %dcr
+	wr 666, %g1, %dcr
+	wr %g1, %g2, %gsr
+	wr %g1, 666, %gsr
+	wr 666, %g1, %gsr
+	wr %g1, %g2, %softint_set
+	wr %g1, 666, %softint_set
+	wr 666, %g1, %softint_set
+	wr %g1, %g2, %softint_clear
+	wr %g1, 666, %softint_clear
+	wr 666, %g1, %softint_clear
+	wr %g1, %g2, %softint
+	wr %g1, 666, %softint
+	wr 666, %g1, %softint
+	wr %g1, %g2, %tick_cmpr
+	wr %g1, 666, %tick_cmpr
+	wr 666, %g1, %tick_cmpr
+	wr %g1, %g2, %sys_tick
+	wr %g1, 666, %sys_tick
+	wr 666, %g1, %sys_tick
+	wr %g1, %g2, %sys_tick_cmpr
+	wr %g1, 666, %sys_tick_cmpr
+	wr 666, %g1, %sys_tick_cmpr
+	wr %g1, %g2, %cfr
+	wr %g1, 666, %cfr
+	wr 666, %g1, %cfr
+	wr %g1, %g2, %pause
+	wr %g1, 666, %pause
+	wr 666, %g1, %pause
+	wr %g1, %g2, %mwait
+	wr %g1, 666, %mwait
+	wr 666, %g1, %mwait
diff --git a/gas/testsuite/gas/sparc/wrhpr.d b/gas/testsuite/gas/sparc/wrhpr.d
index 67d7de3..5b31625 100644
--- a/gas/testsuite/gas/sparc/wrhpr.d
+++ b/gas/testsuite/gas/sparc/wrhpr.d
@@ -1,4 +1,4 @@
-#as: -64 -Av9
+#as: -64 -Av9m
 #objdump: -dr
 #name: sparc64 wrhpr
 
@@ -7,10 +7,53 @@
 Disassembly of section .text:
 
 0+ <.text>:
-   0:	81 98 40 00 	wrhpr  %g1, %hpstate
-   4:	83 98 80 00 	wrhpr  %g2, %htstate
-   8:	87 98 c0 00 	wrhpr  %g3, %hintp
-   c:	8b 99 00 00 	wrhpr  %g4, %htba
-  10:	b9 99 40 00 	wrhpr  %g5, %hstick_offset
-  14:	bb 99 80 00 	wrhpr  %g6, %hstick_enable
-  18:	bf 99 c0 00 	wrhpr  %g7, %hstick_cmpr
+   0:	81 98 40 02 	wrhpr  %g1, %g2, %hpstate
+   4:	81 98 40 00 	wrhpr  %g1, %hpstate
+   8:	81 98 62 9a 	wrhpr  %g1, 0x29a, %hpstate
+   c:	81 98 62 9a 	wrhpr  %g1, 0x29a, %hpstate
+  10:	81 98 22 9a 	wrhpr  0x29a, %hpstate
+  14:	83 98 40 02 	wrhpr  %g1, %g2, %htstate
+  18:	83 98 40 00 	wrhpr  %g1, %htstate
+  1c:	83 98 62 9a 	wrhpr  %g1, 0x29a, %htstate
+  20:	83 98 62 9a 	wrhpr  %g1, 0x29a, %htstate
+  24:	83 98 22 9a 	wrhpr  0x29a, %htstate
+  28:	87 98 40 02 	wrhpr  %g1, %g2, %hintp
+  2c:	87 98 40 00 	wrhpr  %g1, %hintp
+  30:	87 98 62 9a 	wrhpr  %g1, 0x29a, %hintp
+  34:	87 98 62 9a 	wrhpr  %g1, 0x29a, %hintp
+  38:	87 98 22 9a 	wrhpr  0x29a, %hintp
+  3c:	8b 98 40 02 	wrhpr  %g1, %g2, %htba
+  40:	8b 98 40 00 	wrhpr  %g1, %htba
+  44:	8b 98 62 9a 	wrhpr  %g1, 0x29a, %htba
+  48:	8b 98 62 9a 	wrhpr  %g1, 0x29a, %htba
+  4c:	8b 98 22 9a 	wrhpr  0x29a, %htba
+  50:	af 98 40 02 	wrhpr  %g1, %g2, %hmcdper
+  54:	af 98 40 00 	wrhpr  %g1, %hmcdper
+  58:	af 98 62 9a 	wrhpr  %g1, 0x29a, %hmcdper
+  5c:	af 98 62 9a 	wrhpr  %g1, 0x29a, %hmcdper
+  60:	af 98 22 9a 	wrhpr  0x29a, %hmcdper
+  64:	b1 98 40 02 	wrhpr  %g1, %g2, %hmcddfr
+  68:	b1 98 40 00 	wrhpr  %g1, %hmcddfr
+  6c:	b1 98 62 9a 	wrhpr  %g1, 0x29a, %hmcddfr
+  70:	b1 98 62 9a 	wrhpr  %g1, 0x29a, %hmcddfr
+  74:	b1 98 22 9a 	wrhpr  0x29a, %hmcddfr
+  78:	b7 98 40 02 	wrhpr  %g1, %g2, %hva_mask_nz
+  7c:	b7 98 40 00 	wrhpr  %g1, %hva_mask_nz
+  80:	b7 98 62 9a 	wrhpr  %g1, 0x29a, %hva_mask_nz
+  84:	b7 98 62 9a 	wrhpr  %g1, 0x29a, %hva_mask_nz
+  88:	b7 98 22 9a 	wrhpr  0x29a, %hva_mask_nz
+  8c:	b9 98 40 02 	wrhpr  %g1, %g2, %hstick_offset
+  90:	b9 98 40 00 	wrhpr  %g1, %hstick_offset
+  94:	b9 98 62 9a 	wrhpr  %g1, 0x29a, %hstick_offset
+  98:	b9 98 62 9a 	wrhpr  %g1, 0x29a, %hstick_offset
+  9c:	b9 98 22 9a 	wrhpr  0x29a, %hstick_offset
+  a0:	bb 98 40 02 	wrhpr  %g1, %g2, %hstick_enable
+  a4:	bb 98 40 00 	wrhpr  %g1, %hstick_enable
+  a8:	bb 98 62 9a 	wrhpr  %g1, 0x29a, %hstick_enable
+  ac:	bb 98 62 9a 	wrhpr  %g1, 0x29a, %hstick_enable
+  b0:	bb 98 22 9a 	wrhpr  0x29a, %hstick_enable
+  b4:	bf 98 40 02 	wrhpr  %g1, %g2, %hstick_cmpr
+  b8:	bf 98 40 00 	wrhpr  %g1, %hstick_cmpr
+  bc:	bf 98 62 9a 	wrhpr  %g1, 0x29a, %hstick_cmpr
+  c0:	bf 98 62 9a 	wrhpr  %g1, 0x29a, %hstick_cmpr
+  c4:	bf 98 22 9a 	wrhpr  0x29a, %hstick_cmpr
diff --git a/gas/testsuite/gas/sparc/wrhpr.s b/gas/testsuite/gas/sparc/wrhpr.s
index b93733e..2588990 100644
--- a/gas/testsuite/gas/sparc/wrhpr.s
+++ b/gas/testsuite/gas/sparc/wrhpr.s
@@ -1,9 +1,52 @@
 # Test wrpr
 	.text
-	wrhpr %g1,%hpstate
-	wrhpr %g2,%htstate
-	wrhpr %g3,%hintp
-	wrhpr %g4,%htba
-	wrhpr %g5,%hstick_offset
-	wrhpr %g6,%hstick_enable
-	wrhpr %g7,%hstick_cmpr
+	wrhpr %g1, %g2, %hpstate
+	wrhpr %g1, %hpstate
+	wrhpr %g1,666, %hpstate
+	wrhpr 666, %g1, %hpstate
+	wrhpr 666, %hpstate
+	wrhpr %g1, %g2, %htstate
+	wrhpr %g1, %htstate
+	wrhpr %g1,666, %htstate
+	wrhpr 666, %g1, %htstate
+	wrhpr 666, %htstate
+	wrhpr %g1, %g2, %hintp
+	wrhpr %g1, %hintp
+	wrhpr %g1,666, %hintp
+	wrhpr 666, %g1, %hintp
+	wrhpr 666, %hintp
+	wrhpr %g1, %g2, %htba
+	wrhpr %g1, %htba
+	wrhpr %g1,666, %htba
+	wrhpr 666, %g1, %htba
+	wrhpr 666, %htba
+	wrhpr %g1, %g2, %hmcdper
+	wrhpr %g1, %hmcdper
+	wrhpr %g1,666, %hmcdper
+	wrhpr 666, %g1, %hmcdper
+	wrhpr 666, %hmcdper
+	wrhpr %g1, %g2, %hmcddfr
+	wrhpr %g1, %hmcddfr
+	wrhpr %g1,666, %hmcddfr
+	wrhpr 666, %g1, %hmcddfr
+	wrhpr 666, %hmcddfr
+	wrhpr %g1, %g2, %hva_mask_nz
+	wrhpr %g1, %hva_mask_nz
+	wrhpr %g1,666, %hva_mask_nz
+	wrhpr 666, %g1, %hva_mask_nz
+	wrhpr 666, %hva_mask_nz
+	wrhpr %g1, %g2, %hstick_offset
+	wrhpr %g1, %hstick_offset
+	wrhpr %g1,666, %hstick_offset
+	wrhpr 666, %g1, %hstick_offset
+	wrhpr 666, %hstick_offset
+	wrhpr %g1, %g2, %hstick_enable
+	wrhpr %g1, %hstick_enable
+	wrhpr %g1,666, %hstick_enable
+	wrhpr 666, %g1, %hstick_enable
+	wrhpr 666, %hstick_enable
+	wrhpr %g1, %g2, %hstick_cmpr
+	wrhpr %g1, %hstick_cmpr
+	wrhpr %g1,666, %hstick_cmpr
+	wrhpr 666, %g1, %hstick_cmpr
+	wrhpr 666, %hstick_cmpr
diff --git a/gas/testsuite/gas/sparc/wrpr.d b/gas/testsuite/gas/sparc/wrpr.d
index 5a9b6f9..7b724f3 100644
--- a/gas/testsuite/gas/sparc/wrpr.d
+++ b/gas/testsuite/gas/sparc/wrpr.d
@@ -1,4 +1,4 @@
-#as: -64 -Av9
+#as: -64 -Av9m
 #objdump: -dr
 #name: sparc64 wrpr
 
@@ -7,20 +7,98 @@
 Disassembly of section .text:
 
 0+ <.text>:
-   0:	81 90 40 00 	wrpr  %g1, %tpc
-   4:	83 90 80 00 	wrpr  %g2, %tnpc
-   8:	85 90 c0 00 	wrpr  %g3, %tstate
-   c:	87 91 00 00 	wrpr  %g4, %tt
-  10:	89 91 40 00 	wrpr  %g5, %tick
-  14:	8b 91 80 00 	wrpr  %g6, %tba
-  18:	8d 91 c0 00 	wrpr  %g7, %pstate
-  1c:	8f 92 00 00 	wrpr  %o0, %tl
-  20:	91 92 40 00 	wrpr  %o1, %pil
-  24:	93 92 80 00 	wrpr  %o2, %cwp
-  28:	95 92 c0 00 	wrpr  %o3, %cansave
-  2c:	97 93 00 00 	wrpr  %o4, %canrestore
-  30:	99 93 40 00 	wrpr  %o5, %cleanwin
-  34:	9b 93 80 00 	wrpr  %sp, %otherwin
-  38:	9d 93 c0 00 	wrpr  %o7, %wstate
-  3c:	a1 94 00 00 	wrpr  %l0, %gl
-  40:	af 94 c0 00 	wrpr  %l3, %pmcdper
+   0:	81 90 40 02 	wrpr  %g1, %g2, %tpc
+   4:	81 90 40 00 	wrpr  %g1, %tpc
+   8:	81 90 62 9a 	wrpr  %g1, 0x29a, %tpc
+   c:	81 90 62 9a 	wrpr  %g1, 0x29a, %tpc
+  10:	81 90 22 9a 	wrpr  0x29a, %tpc
+  14:	83 90 40 02 	wrpr  %g1, %g2, %tnpc
+  18:	83 90 40 00 	wrpr  %g1, %tnpc
+  1c:	83 90 62 9a 	wrpr  %g1, 0x29a, %tnpc
+  20:	83 90 62 9a 	wrpr  %g1, 0x29a, %tnpc
+  24:	83 90 22 9a 	wrpr  0x29a, %tnpc
+  28:	85 90 40 02 	wrpr  %g1, %g2, %tstate
+  2c:	85 90 40 00 	wrpr  %g1, %tstate
+  30:	85 90 62 9a 	wrpr  %g1, 0x29a, %tstate
+  34:	85 90 62 9a 	wrpr  %g1, 0x29a, %tstate
+  38:	85 90 22 9a 	wrpr  0x29a, %tstate
+  3c:	87 90 40 02 	wrpr  %g1, %g2, %tt
+  40:	87 90 40 00 	wrpr  %g1, %tt
+  44:	87 90 62 9a 	wrpr  %g1, 0x29a, %tt
+  48:	87 90 62 9a 	wrpr  %g1, 0x29a, %tt
+  4c:	87 90 22 9a 	wrpr  0x29a, %tt
+  50:	89 90 40 02 	wrpr  %g1, %g2, %tick
+  54:	89 90 40 00 	wrpr  %g1, %tick
+  58:	89 90 62 9a 	wrpr  %g1, 0x29a, %tick
+  5c:	89 90 62 9a 	wrpr  %g1, 0x29a, %tick
+  60:	89 90 22 9a 	wrpr  0x29a, %tick
+  64:	8b 90 40 02 	wrpr  %g1, %g2, %tba
+  68:	8b 90 40 00 	wrpr  %g1, %tba
+  6c:	8b 90 62 9a 	wrpr  %g1, 0x29a, %tba
+  70:	8b 90 62 9a 	wrpr  %g1, 0x29a, %tba
+  74:	8b 90 22 9a 	wrpr  0x29a, %tba
+  78:	8d 90 40 02 	wrpr  %g1, %g2, %pstate
+  7c:	8d 90 40 00 	wrpr  %g1, %pstate
+  80:	8d 90 62 9a 	wrpr  %g1, 0x29a, %pstate
+  84:	8d 90 62 9a 	wrpr  %g1, 0x29a, %pstate
+  88:	8d 90 22 9a 	wrpr  0x29a, %pstate
+  8c:	8f 90 40 02 	wrpr  %g1, %g2, %tl
+  90:	8f 90 40 00 	wrpr  %g1, %tl
+  94:	8f 90 62 9a 	wrpr  %g1, 0x29a, %tl
+  98:	8f 90 62 9a 	wrpr  %g1, 0x29a, %tl
+  9c:	8f 90 22 9a 	wrpr  0x29a, %tl
+  a0:	91 90 40 02 	wrpr  %g1, %g2, %pil
+  a4:	91 90 40 00 	wrpr  %g1, %pil
+  a8:	91 90 62 9a 	wrpr  %g1, 0x29a, %pil
+  ac:	91 90 62 9a 	wrpr  %g1, 0x29a, %pil
+  b0:	91 90 22 9a 	wrpr  0x29a, %pil
+  b4:	93 90 40 02 	wrpr  %g1, %g2, %cwp
+  b8:	93 90 40 00 	wrpr  %g1, %cwp
+  bc:	93 90 62 9a 	wrpr  %g1, 0x29a, %cwp
+  c0:	93 90 62 9a 	wrpr  %g1, 0x29a, %cwp
+  c4:	93 90 22 9a 	wrpr  0x29a, %cwp
+  c8:	95 90 40 02 	wrpr  %g1, %g2, %cansave
+  cc:	95 90 40 00 	wrpr  %g1, %cansave
+  d0:	95 90 62 9a 	wrpr  %g1, 0x29a, %cansave
+  d4:	95 90 62 9a 	wrpr  %g1, 0x29a, %cansave
+  d8:	95 90 22 9a 	wrpr  0x29a, %cansave
+  dc:	97 90 40 02 	wrpr  %g1, %g2, %canrestore
+  e0:	97 90 40 00 	wrpr  %g1, %canrestore
+  e4:	97 90 62 9a 	wrpr  %g1, 0x29a, %canrestore
+  e8:	97 90 62 9a 	wrpr  %g1, 0x29a, %canrestore
+  ec:	97 90 22 9a 	wrpr  0x29a, %canrestore
+  f0:	99 90 40 02 	wrpr  %g1, %g2, %cleanwin
+  f4:	99 90 40 00 	wrpr  %g1, %cleanwin
+  f8:	99 90 62 9a 	wrpr  %g1, 0x29a, %cleanwin
+  fc:	99 90 62 9a 	wrpr  %g1, 0x29a, %cleanwin
+ 100:	99 90 22 9a 	wrpr  0x29a, %cleanwin
+ 104:	9b 90 40 02 	wrpr  %g1, %g2, %otherwin
+ 108:	9b 90 40 00 	wrpr  %g1, %otherwin
+ 10c:	9b 90 62 9a 	wrpr  %g1, 0x29a, %otherwin
+ 110:	9b 90 62 9a 	wrpr  %g1, 0x29a, %otherwin
+ 114:	9b 90 22 9a 	wrpr  0x29a, %otherwin
+ 118:	9d 90 40 02 	wrpr  %g1, %g2, %wstate
+ 11c:	9d 90 40 00 	wrpr  %g1, %wstate
+ 120:	9d 90 62 9a 	wrpr  %g1, 0x29a, %wstate
+ 124:	9d 90 62 9a 	wrpr  %g1, 0x29a, %wstate
+ 128:	9d 90 22 9a 	wrpr  0x29a, %wstate
+ 12c:	9f 90 40 02 	wrpr  %g1, %g2, %fq
+ 130:	9f 90 40 00 	wrpr  %g1, %fq
+ 134:	9f 90 62 9a 	wrpr  %g1, 0x29a, %fq
+ 138:	9f 90 62 9a 	wrpr  %g1, 0x29a, %fq
+ 13c:	9f 90 22 9a 	wrpr  0x29a, %fq
+ 140:	a1 90 40 02 	wrpr  %g1, %g2, %gl
+ 144:	a1 90 40 00 	wrpr  %g1, %gl
+ 148:	a1 90 62 9a 	wrpr  %g1, 0x29a, %gl
+ 14c:	a1 90 62 9a 	wrpr  %g1, 0x29a, %gl
+ 150:	a1 90 22 9a 	wrpr  0x29a, %gl
+ 154:	af 90 40 02 	wrpr  %g1, %g2, %pmcdper
+ 158:	af 90 40 00 	wrpr  %g1, %pmcdper
+ 15c:	af 90 62 9a 	wrpr  %g1, 0x29a, %pmcdper
+ 160:	af 90 62 9a 	wrpr  %g1, 0x29a, %pmcdper
+ 164:	af 90 22 9a 	wrpr  0x29a, %pmcdper
+ 168:	bf 90 40 02 	wrpr  %g1, %g2, %ver
+ 16c:	bf 90 40 00 	wrpr  %g1, %ver
+ 170:	bf 90 62 9a 	wrpr  %g1, 0x29a, %ver
+ 174:	bf 90 62 9a 	wrpr  %g1, 0x29a, %ver
+ 178:	bf 90 22 9a 	wrpr  0x29a, %ver
diff --git a/gas/testsuite/gas/sparc/wrpr.s b/gas/testsuite/gas/sparc/wrpr.s
index a17182e..2227fe0 100644
--- a/gas/testsuite/gas/sparc/wrpr.s
+++ b/gas/testsuite/gas/sparc/wrpr.s
@@ -1,19 +1,97 @@
 # Test wrpr
 	.text
+	wrpr %g1,%g2,%tpc
 	wrpr %g1,%tpc
-	wrpr %g2,%tnpc
-	wrpr %g3,%tstate
-	wrpr %g4,%tt
-	wrpr %g5,%tick
-	wrpr %g6,%tba
-	wrpr %g7,%pstate
-	wrpr %o0,%tl
-	wrpr %o1,%pil
-	wrpr %o2,%cwp
-	wrpr %o3,%cansave
-	wrpr %o4,%canrestore
-	wrpr %o5,%cleanwin
-	wrpr %o6,%otherwin
-	wrpr %o7,%wstate
-	wrpr %l0,%gl
-	wrpr %l3,%pmcdper
+	wrpr %g1,666,%tpc
+	wrpr 666,%g1,%tpc
+	wrpr 666,%tpc
+	wrpr %g1,%g2,%tnpc
+	wrpr %g1,%tnpc
+	wrpr %g1,666,%tnpc
+	wrpr 666,%g1,%tnpc
+	wrpr 666,%tnpc
+	wrpr %g1,%g2,%tstate
+	wrpr %g1,%tstate
+	wrpr %g1,666,%tstate
+	wrpr 666,%g1,%tstate
+	wrpr 666,%tstate
+	wrpr %g1,%g2,%tt
+	wrpr %g1,%tt
+	wrpr %g1,666,%tt
+	wrpr 666,%g1,%tt
+	wrpr 666,%tt
+	wrpr %g1,%g2,%tick
+	wrpr %g1,%tick
+	wrpr %g1,666,%tick
+	wrpr 666,%g1,%tick
+	wrpr 666,%tick
+	wrpr %g1,%g2,%tba
+	wrpr %g1,%tba
+	wrpr %g1,666,%tba
+	wrpr 666,%g1,%tba
+	wrpr 666,%tba
+	wrpr %g1,%g2,%pstate
+	wrpr %g1,%pstate
+	wrpr %g1,666,%pstate
+	wrpr 666,%g1,%pstate
+	wrpr 666,%pstate
+	wrpr %g1,%g2,%tl
+	wrpr %g1,%tl
+	wrpr %g1,666,%tl
+	wrpr 666,%g1,%tl
+	wrpr 666,%tl
+	wrpr %g1,%g2,%pil
+	wrpr %g1,%pil
+	wrpr %g1,666,%pil
+	wrpr 666,%g1,%pil
+	wrpr 666,%pil
+	wrpr %g1,%g2,%cwp
+	wrpr %g1,%cwp
+	wrpr %g1,666,%cwp
+	wrpr 666,%g1,%cwp
+	wrpr 666,%cwp
+	wrpr %g1,%g2,%cansave
+	wrpr %g1,%cansave
+	wrpr %g1,666,%cansave
+	wrpr 666,%g1,%cansave
+	wrpr 666,%cansave
+	wrpr %g1,%g2,%canrestore
+	wrpr %g1,%canrestore
+	wrpr %g1,666,%canrestore
+	wrpr 666,%g1,%canrestore
+	wrpr 666,%canrestore
+	wrpr %g1,%g2,%cleanwin
+	wrpr %g1,%cleanwin
+	wrpr %g1,666,%cleanwin
+	wrpr 666,%g1,%cleanwin
+	wrpr 666,%cleanwin
+	wrpr %g1,%g2,%otherwin
+	wrpr %g1,%otherwin
+	wrpr %g1,666,%otherwin
+	wrpr 666,%g1,%otherwin
+	wrpr 666,%otherwin
+	wrpr %g1,%g2,%wstate
+	wrpr %g1,%wstate
+	wrpr %g1,666,%wstate
+	wrpr 666,%g1,%wstate
+	wrpr 666,%wstate
+	wrpr %g1,%g2,%fq
+	wrpr %g1,%fq
+	wrpr %g1,666,%fq
+	wrpr 666,%g1,%fq
+	wrpr 666,%fq
+	wrpr %g1,%g2,%gl
+	wrpr %g1,%gl
+	wrpr %g1,666,%gl
+	wrpr 666,%g1,%gl
+	wrpr 666,%gl
+	wrpr %g1,%g2,%pmcdper
+	wrpr %g1,%pmcdper
+	wrpr %g1,666,%pmcdper
+	wrpr 666,%g1,%pmcdper
+	wrpr 666,%pmcdper
+	wrpr %g1,%g2,%ver
+	wrpr %g1,%ver
+	wrpr %g1,666,%ver
+	wrpr 666,%g1,%ver
+	wrpr 666,%ver
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index 89c55ef..21d9276 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,5 +1,21 @@
 2016-06-15  Jose E. Marchesi  <jose.marchesi@oracle.com>
 
+	* sparc-opc.c (rdasr): New macro.
+	(wrasr): Likewise.
+	(rdpr): Likewise.
+	(wrpr): Likewise.
+	(rdhpr): Likewise.
+	(wrhpr): Likewise.
+	(sparc_opcodes): Use the macros above to fix and expand the
+	definition of read/write instructions from/to
+	asr/privileged/hyperprivileged instructions.
+	* sparc-dis.c (v9_hpriv_reg_names): Add %hmcdper, %hmcddfr and
+	%hva_mask_nz.  Prefer softint_set and softint_clear over
+	set_softint and clear_softint.
+	(print_insn_sparc): Support %ver in Rd.
+
+2016-06-15  Jose E. Marchesi  <jose.marchesi@oracle.com>
+
 	* sparc-opc.c (sparc_opcodes): Adjust instructions opcode
 	architecture according to the hardware capabilities they require.
 
diff --git a/opcodes/sparc-dis.c b/opcodes/sparc-dis.c
index c6f73ff..d48dee5 100644
--- a/opcodes/sparc-dis.c
+++ b/opcodes/sparc-dis.c
@@ -101,7 +101,7 @@ static char *v9_hpriv_reg_names[] =
   "hpstate", "htstate", "resv2", "hintp", "resv4", "htba", "hver",
   "resv7", "resv8", "resv9", "resv10", "resv11", "resv12", "resv13",
   "resv14", "resv15", "resv16", "resv17", "resv18", "resv19", "resv20",
-  "resv21", "resv22", "resv23", "resv24", "resv25", "resv26", "resv27",
+  "resv21", "resv22", "hmcdper", "hmcddfr", "resv25", "resv26", "hva_mask_nz",
   "hstick_offset", "hstick_enable", "resv30", "hstick_cmpr"
 };
 
@@ -109,7 +109,7 @@ static char *v9_hpriv_reg_names[] =
    rd and wr insns (-16).  */
 static char *v9a_asr_reg_names[] =
 {
-  "pcr", "pic", "dcr", "gsr", "set_softint", "clear_softint",
+  "pcr", "pic", "dcr", "gsr", "softint_set", "softint_clear",
   "softint", "tick_cmpr", "stick", "stick_cmpr", "cfr",
   "pause", "mwait"
 };
@@ -843,7 +843,9 @@ print_insn_sparc (bfd_vma memaddr, disassemble_info *info)
 		    break;
 
 		  case '!':
-		    if (X_RD (insn) == 23)
+                    if (X_RD (insn) == 31)
+                      (*info->fprintf_func) (stream, "%%ver");
+		    else if (X_RD (insn) == 23)
 		      (*info->fprintf_func) (stream, "%%pmcdper");
 		    else if ((unsigned) X_RD (insn) < 17)
 		      (*info->fprintf_func) (stream, "%%%s",
diff --git a/opcodes/sparc-opc.c b/opcodes/sparc-opc.c
index e4bdd9b..ec44fb0 100644
--- a/opcodes/sparc-opc.c
+++ b/opcodes/sparc-opc.c
@@ -940,32 +940,28 @@ const struct sparc_opcode sparc_opcodes[] = {
 { "wr", F3(2, 0x30, 0)|RD(14),  F3(~2, ~0x30, ~0)|RD(~14),              "1,2,{", 0, 0, HWCAP2_SPARC5, v9m }, /* wr r,r,%mcdper */
 { "wr", F3(2, 0x30, 1)|RD(14),  F3(~2, ~0x30, ~1)|RD(~14),              "1,i,{", 0, 0, HWCAP2_SPARC5, v9m }, /* wr r,i,%mcdper */
 
-{ "wr", F3(2, 0x30, 0)|RD(16),	F3(~2, ~0x30, ~0)|RD(~16)|ASI(~0),	"1,2,_", 0, HWCAP_VIS, 0, v9a }, /* wr r,r,%pcr */
-{ "wr", F3(2, 0x30, 1)|RD(16),	F3(~2, ~0x30, ~1)|RD(~16),		"1,i,_", 0, HWCAP_VIS, 0, v9a }, /* wr r,i,%pcr */
-{ "wr", F3(2, 0x30, 0)|RD(17),	F3(~2, ~0x30, ~0)|RD(~17)|ASI(~0),	"1,2,_", 0, HWCAP_VIS, 0, v9a }, /* wr r,r,%pic */
-{ "wr", F3(2, 0x30, 1)|RD(17),	F3(~2, ~0x30, ~1)|RD(~17),		"1,i,_", 0, HWCAP_VIS, 0, v9a }, /* wr r,i,%pic */
-{ "wr", F3(2, 0x30, 0)|RD(18),	F3(~2, ~0x30, ~0)|RD(~18)|ASI(~0),	"1,2,_", 0, HWCAP_VIS, 0, v9a }, /* wr r,r,%dcr */
-{ "wr", F3(2, 0x30, 1)|RD(18),	F3(~2, ~0x30, ~1)|RD(~18),		"1,i,_", 0, HWCAP_VIS, 0, v9a }, /* wr r,i,%dcr */
-{ "wr", F3(2, 0x30, 0)|RD(19),	F3(~2, ~0x30, ~0)|RD(~19)|ASI(~0),	"1,2,_", 0, HWCAP_VIS, 0, v9a }, /* wr r,r,%gsr */
-{ "wr", F3(2, 0x30, 1)|RD(19),	F3(~2, ~0x30, ~1)|RD(~19),		"1,i,_", 0, HWCAP_VIS, 0, v9a }, /* wr r,i,%gsr */
-{ "wr", F3(2, 0x30, 0)|RD(20),	F3(~2, ~0x30, ~0)|RD(~20)|ASI(~0),	"1,2,_", 0, HWCAP_VIS, 0, v9a }, /* wr r,r,%set_softint */
-{ "wr", F3(2, 0x30, 1)|RD(20),	F3(~2, ~0x30, ~1)|RD(~20),		"1,i,_", 0, HWCAP_VIS, 0, v9a }, /* wr r,i,%set_softint */
-{ "wr", F3(2, 0x30, 0)|RD(21),	F3(~2, ~0x30, ~0)|RD(~21)|ASI(~0),	"1,2,_", 0, HWCAP_VIS, 0, v9a }, /* wr r,r,%clear_softint */
-{ "wr", F3(2, 0x30, 1)|RD(21),	F3(~2, ~0x30, ~1)|RD(~21),		"1,i,_", 0, HWCAP_VIS, 0, v9a }, /* wr r,i,%clear_softint */
-{ "wr", F3(2, 0x30, 0)|RD(22),	F3(~2, ~0x30, ~0)|RD(~22)|ASI(~0),	"1,2,_", 0, HWCAP_VIS, 0, v9a }, /* wr r,r,%softint */
-{ "wr", F3(2, 0x30, 1)|RD(22),	F3(~2, ~0x30, ~1)|RD(~22),		"1,i,_", 0, HWCAP_VIS, 0, v9a }, /* wr r,i,%softint */
-{ "wr", F3(2, 0x30, 0)|RD(23),	F3(~2, ~0x30, ~0)|RD(~23)|ASI(~0),	"1,2,_", 0, HWCAP_VIS, 0, v9a }, /* wr r,r,%tick_cmpr */
-{ "wr", F3(2, 0x30, 1)|RD(23),	F3(~2, ~0x30, ~1)|RD(~23),		"1,i,_", 0, HWCAP_VIS, 0, v9a }, /* wr r,i,%tick_cmpr */
-{ "wr", F3(2, 0x30, 0)|RD(24),	F3(~2, ~0x30, ~0)|RD(~24)|ASI(~0),	"1,2,_", 0, HWCAP_VIS2, 0, v9b }, /* wr r,r,%sys_tick */
-{ "wr", F3(2, 0x30, 1)|RD(24),	F3(~2, ~0x30, ~1)|RD(~24),		"1,i,_", 0, HWCAP_VIS2, 0, v9b }, /* wr r,i,%sys_tick */
-{ "wr", F3(2, 0x30, 0)|RD(25),	F3(~2, ~0x30, ~0)|RD(~25)|ASI(~0),	"1,2,_", 0, HWCAP_VIS2, 0, v9b }, /* wr r,r,%sys_tick_cmpr */
-{ "wr", F3(2, 0x30, 1)|RD(25),	F3(~2, ~0x30, ~1)|RD(~25),		"1,i,_", 0, HWCAP_VIS2, 0, v9b }, /* wr r,i,%sys_tick_cmpr */
-{ "wr", F3(2, 0x30, 0)|RD(26),	F3(~2, ~0x30, ~0)|RD(~26)|ASI(~0),	"1,2,_", 0, HWCAP_CBCOND, 0, v9e }, /* wr r,r,%cfr */
-{ "wr", F3(2, 0x30, 1)|RD(26),	F3(~2, ~0x30, ~1)|RD(~26),		"1,i,_", 0, HWCAP_CBCOND, 0, v9e }, /* wr r,i,%cfr */
-{ "wr", F3(2, 0x30, 0)|RD(27),	F3(~2, ~0x30, ~0)|RD(~27)|ASI(~0),	"1,2,_", 0, HWCAP_PAUSE, 0, v9e }, /* wr r,r,%pause */
-{ "wr", F3(2, 0x30, 1)|RD(27),	F3(~2, ~0x30, ~1)|RD(~27),		"1,i,_", 0, HWCAP_PAUSE, 0, v9e }, /* wr r,i,%pause */
-{ "wr",    F3(2, 0x30, 0)|RD(28), F3(~2, ~0x30, ~0)|RD(~28)|ASI(~0), "1,2,_", 0, 0, HWCAP2_MWAIT, v9m }, /* wr r,r,%mwait */
-{ "wr", F3(2, 0x30, 1)|RD(28),	F3(~2, ~0x30, ~1)|RD(~28),		"1,i,_", 0, 0, HWCAP2_MWAIT, v9m }, /* wr r,i,%mwait */
+/* Write to ASR registers 16..31, which is the range defined in SPARC
+   V9 for implementation-dependent uses.  Note that the read-only ASR
+   registers can't be used in a `wr' instruction.  */
+
+#define wrasr(asr,hwcap,hwcap2,arch) \
+{ "wr", F3(2, 0x30, 0)|RD((asr)), F3(~2, ~0x30, ~0)|RD(~(asr))|ASI(~0),	"1,2,_", 0, (hwcap), (hwcap2), (arch) }, /* wr r,r,%asr */ \
+{ "wr", F3(2, 0x30, 1)|RD((asr)), F3(~2, ~0x30, ~1)|RD(~(asr)),		"1,i,_", 0, (hwcap), (hwcap2), (arch) }, /* wr r,i,%asr */ \
+{ "wr", F3(2, 0x30, 1)|RD((asr)), F3(~2, ~0x30, ~1)|RD(~(asr)),		"i,1,_", F_ALIAS, (hwcap), (hwcap2), (arch) } /* wr i,r,%asr */
+
+wrasr (16, HWCAP_VIS, 0, v9a), /* wr ...,%pcr  */
+wrasr (17, HWCAP_VIS, 0, v9a), /* wr ...,%pic  */
+wrasr (18, HWCAP_VIS, 0, v9a), /* wr ...,%dcr  */
+wrasr (19, HWCAP_VIS, 0, v9a), /* wr ...,%gsr  */
+wrasr (20, HWCAP_VIS, 0, v9a), /* wr ...,%softint_set  */
+wrasr (21, HWCAP_VIS, 0, v9a), /* wr ...,%softint_clear  */
+wrasr (22, HWCAP_VIS, 0, v9a), /* wr ...,%softint  */
+wrasr (23, HWCAP_VIS, 0, v9a), /* wr ...,%tick_cmpr  */
+wrasr (24, HWCAP_VIS2, 0, v9b), /* wr ...,%sys_tick  */
+wrasr (25, HWCAP_VIS2, 0, v9b), /* wr ...,%sys_tick_cmpr  */
+wrasr (26, HWCAP_CBCOND, 0, v9e), /* wr ...,%cfr  */
+wrasr (27, HWCAP_PAUSE, 0, v9e),  /* wr ...,%pause  */
+wrasr (28, 0, HWCAP2_MWAIT, v9m), /* wr ...,%mwait  */
 
 { "pause", F3(2, 0x30, 1)|RD(27)|RS1(0), F3(~2, ~0x30, ~1)|RD(~27)|RS1(~0), "i", 0, HWCAP_PAUSE, 0, v9e }, /* wr %g0,i,%pause */
 
@@ -976,16 +972,22 @@ const struct sparc_opcode sparc_opcodes[] = {
 { "rd",	F3(2, 0x28, 0)|RS1(6),		F3(~2, ~0x28, ~0)|RS1(~6)|SIMM13(~0),	"s,d", 0, 0, 0, v9 }, /* rd %fprs,r */
 { "rd", F3(2, 0x28, 0)|RS1(14),         F3(~2, ~0x28, ~0)|RS1(~14)|SIMM13(~0),  "{,d", 0, 0, HWCAP2_SPARC5, v9m }, /* rd %mcdper,r */
 
-{ "rd",	F3(2, 0x28, 0)|RS1(16),		F3(~2, ~0x28, ~0)|RS1(~16)|SIMM13(~0),	"/,d", 0, HWCAP_VIS, 0, v9a }, /* rd %pcr,r */
-{ "rd",	F3(2, 0x28, 0)|RS1(17),		F3(~2, ~0x28, ~0)|RS1(~17)|SIMM13(~0),	"/,d", 0, HWCAP_VIS, 0, v9a }, /* rd %pic,r */
-{ "rd",	F3(2, 0x28, 0)|RS1(18),		F3(~2, ~0x28, ~0)|RS1(~18)|SIMM13(~0),	"/,d", 0, HWCAP_VIS, 0, v9a }, /* rd %dcr,r */
-{ "rd",	F3(2, 0x28, 0)|RS1(19),		F3(~2, ~0x28, ~0)|RS1(~19)|SIMM13(~0),	"/,d", 0, HWCAP_VIS, 0, v9a }, /* rd %gsr,r */
-{ "rd",	F3(2, 0x28, 0)|RS1(22),		F3(~2, ~0x28, ~0)|RS1(~22)|SIMM13(~0),	"/,d", 0, HWCAP_VIS, 0, v9a }, /* rd %softint,r */
-{ "rd",	F3(2, 0x28, 0)|RS1(23),		F3(~2, ~0x28, ~0)|RS1(~23)|SIMM13(~0),	"/,d", 0, HWCAP_VIS, 0, v9a }, /* rd %tick_cmpr,r */
-{ "rd",	F3(2, 0x28, 0)|RS1(24),		F3(~2, ~0x28, ~0)|RS1(~24)|SIMM13(~0),	"/,d", 0, HWCAP_VIS2, 0, v9b }, /* rd %sys_tick,r */
-{ "rd",	F3(2, 0x28, 0)|RS1(25),		F3(~2, ~0x28, ~0)|RS1(~25)|SIMM13(~0),	"/,d", 0, HWCAP_VIS2, 0, v9b }, /* rd %sys_tick_cmpr,r */
-{ "rd",	F3(2, 0x28, 0)|RS1(26),		F3(~2, ~0x28, ~0)|RS1(~26)|SIMM13(~0),	"/,d", 0, HWCAP_CBCOND, 0, v9e }, /* rd %cfr,r */
-{ "rd",	F3(2, 0x28, 0)|RS1(28),		F3(~2, ~0x28, ~0)|RS1(~28)|SIMM13(~0),	"/,d", 0, 0, HWCAP2_MWAIT, v9m }, /* rd %mwait,r */
+/* Read from ASR registers 16..31, which is the range defined in SPARC
+   V9 for implementation-dependent uses.  Note that the write-only ASR
+   registers can't be used in a `rd' instruction.  */
+
+#define rdasr(asr,hwcap,hwcap2,arch) \
+  { "rd", F3(2, 0x28, 0)|RS1((asr)),	F3(~2, ~0x28, ~0)|RS1(~(asr))|SIMM13(~0), "/,d", 0, (hwcap), (hwcap2), (arch) }
+
+rdasr (16, HWCAP_VIS,    0, v9a), /* rd %pcr,r  */
+rdasr (17, HWCAP_VIS,    0, v9a), /* rd %pic,r  */
+rdasr (18, HWCAP_VIS,    0, v9a), /* rd %dcr,r  */
+rdasr (19, HWCAP_VIS,    0, v9a), /* rd %gsr,r  */
+rdasr (22, HWCAP_VIS,    0, v9a), /* rd %softint,r  */
+rdasr (23, HWCAP_VIS,    0, v9a), /* rd %tick_cmpr,r  */
+rdasr (24, HWCAP_VIS2,   0, v9b), /* rd %sys_tick,r  */
+rdasr (25, HWCAP_VIS2,   0, v9b), /* rd %sys_tick_cmpr,r  */
+rdasr (26, HWCAP_CBCOND, 0, v9e), /* rd %cfr,r  */
 
 { "rd",	F3(2, 0x28, 0),			F3(~2, ~0x28, ~0)|SIMM13(~0),		"M,d", 0, 0, 0, v8 }, /* rd %asrX,r */
 { "rd",	F3(2, 0x28, 0),			F3(~2, ~0x28, ~0)|RS1_G0|SIMM13(~0),	"y,d", 0, 0, 0, v6 }, /* rd %y,r */
@@ -993,19 +995,93 @@ const struct sparc_opcode sparc_opcodes[] = {
 { "rd",	F3(2, 0x2a, 0),			F3(~2, ~0x2a, ~0)|RS1_G0|SIMM13(~0),	"w,d", 0, 0, 0, v6notv9 }, /* rd %wim,r */
 { "rd",	F3(2, 0x2b, 0),			F3(~2, ~0x2b, ~0)|RS1_G0|SIMM13(~0),	"t,d", 0, 0, 0, v6notv9 }, /* rd %tbr,r */
 
-{ "rdpr",	F3(2, 0x2a, 0),		F3(~2, ~0x2a, ~0)|SIMM13(~0),	"?,d", 0, 0, 0, v9 },   /* rdpr %priv,r */
-{ "wrpr",	F3(2, 0x32, 0),		F3(~2, ~0x32, ~0),		"1,2,!", 0, 0, 0, v9 }, /* wrpr r1,r2,%priv */
-{ "wrpr",	F3(2, 0x32, 0),		F3(~2, ~0x32, ~0)|SIMM13(~0),	"1,!", 0, 0, 0, v9 },   /* wrpr r1,%priv */
-{ "wrpr",	F3(2, 0x32, 1),		F3(~2, ~0x32, ~1),		"1,i,!", 0, 0, 0, v9 }, /* wrpr r1,i,%priv */
-{ "wrpr",	F3(2, 0x32, 1),		F3(~2, ~0x32, ~1),		"i,1,!", F_ALIAS, 0, 0, v9 }, /* wrpr i,r1,%priv */
-{ "wrpr",	F3(2, 0x32, 1),		F3(~2, ~0x32, ~1)|RS1(~0),	"i,!", 0, 0, 0, v9 },   /* wrpr i,%priv */
-
-{ "rdhpr",	F3(2, 0x29, 0),		F3(~2, ~0x29, ~0)|SIMM13(~0),	"$,d", 0, 0, 0, v9 },   /* rdhpr %hpriv,r */
-{ "wrhpr",	F3(2, 0x33, 0),		F3(~2, ~0x33, ~0),		"1,2,%", 0, 0, 0, v9 }, /* wrhpr r1,r2,%hpriv */
-{ "wrhpr",	F3(2, 0x33, 0),		F3(~2, ~0x33, ~0)|SIMM13(~0),	"1,%", 0, 0, 0, v9 },   /* wrhpr r1,%hpriv */
-{ "wrhpr",	F3(2, 0x33, 1),		F3(~2, ~0x33, ~1),		"1,i,%", 0, 0, 0, v9 }, /* wrhpr r1,i,%hpriv */
-{ "wrhpr",	F3(2, 0x33, 1),		F3(~2, ~0x33, ~1),		"i,1,%", F_ALIAS, 0, 0, v9 }, /* wrhpr i,r1,%hpriv */
-{ "wrhpr",	F3(2, 0x33, 1),		F3(~2, ~0x33, ~1)|RS1(~0),	"i,%", 0, 0, 0, v9 },   /* wrhpr i,%hpriv */
+/* Instructions to read and write from/to privileged registers.  */
+
+#define rdpr(reg,hwcap,hwcap2,arch) \
+  { "rdpr", F3(2, 0x2a, 0)|RS1((reg)), F3(~2, ~0x2a, ~0)|RS1(~(reg))|SIMM13(~0),"?,d", 0, (hwcap), (hwcap2), (arch) } /* rdpr %priv,r */
+
+rdpr (0, 0, 0, v9), /* rdpr %tpc,r  */
+rdpr (1, 0, 0, v9), /* rdpr %tnpc,r  */
+rdpr (2, 0, 0, v9), /* rdpr %tstate,r  */
+rdpr (3, 0, 0, v9), /* rdpr %tt,r  */
+rdpr (4, 0, 0, v9), /* rdpr %tick,r  */
+rdpr (5, 0, 0, v9), /* rdpr %tba,r  */
+rdpr (6, 0, 0, v9), /* rdpr %pstate,r  */
+rdpr (7, 0, 0, v9), /* rdpr %tl,r  */
+rdpr (8, 0, 0, v9), /* rdpr %pil,r  */
+rdpr (9, 0, 0, v9), /* rdpr %cwp,r  */
+rdpr (10, 0, 0, v9), /* rdpr %cansave,r  */
+rdpr (11, 0, 0, v9), /* rdpr %canrestore,r  */
+rdpr (12, 0, 0, v9), /* rdpr %cleanwin,r  */
+rdpr (13, 0, 0, v9), /* rdpr %otherwin,r  */
+rdpr (14, 0, 0, v9), /* rdpr %wstate,r  */
+rdpr (15, 0, 0, v9), /* rdpr %fq,r  */
+rdpr (16, 0, 0, v9), /* rdpr %gl,r  */
+rdpr (23, 0, HWCAP2_SPARC5, v9m), /* rdpr %pmcdper,r  */
+rdpr (31, 0, 0, v9), /* rdpr %ver,r  */
+
+#define wrpr(reg,hwcap,hwcap2,arch) \
+{ "wrpr", F3(2, 0x32, 0)|RD((reg)), F3(~2, ~0x32, ~0)|RD(~(reg)), "1,2,!", 0, (hwcap), (hwcap2), (arch) }, /* wrpr r1,r2,%priv */ \
+{ "wrpr", F3(2, 0x32, 0)|RD((reg)), F3(~2, ~0x32, ~0)|RD(~(reg))|SIMM13(~0), "1,!", 0, (hwcap), (hwcap2), (arch) }, /* wrpr r1,%priv */ \
+{ "wrpr", F3(2, 0x32, 1)|RD((reg)), F3(~2, ~0x32, ~1)|RD(~(reg)), "1,i,!", 0, (hwcap), (hwcap2), (arch) }, /* wrpr r1,i,%priv */ \
+{ "wrpr", F3(2, 0x32, 1)|RD((reg)), F3(~2, ~0x32, ~1)|RD(~(reg)), "i,1,!", F_ALIAS, (hwcap), (hwcap2), (arch) }, /* wrpr i,r1,%priv */ \
+{ "wrpr", F3(2, 0x32, 1)|RD((reg)), F3(~2, ~0x32, ~1)|RD(~(reg))|RS1(~0), "i,!", 0, (hwcap), (hwcap2), (arch) } /* wrpr i,%priv */
+
+wrpr (0, 0, 0, v9), /* wrpr ...,%tpc  */
+wrpr (1, 0, 0, v9), /* wrpr ...,%tnpc  */
+wrpr (2, 0, 0, v9), /* wrpr ...,%tstate  */
+wrpr (3, 0, 0, v9), /* wrpr ...,%tt  */
+wrpr (4, 0, 0, v9), /* wrpr ...,%tick  */
+wrpr (5, 0, 0, v9), /* wrpr ...,%tba  */
+wrpr (6, 0, 0, v9), /* wrpr ...,%pstate  */
+wrpr (7, 0, 0, v9), /* wrpr ...,%tl  */
+wrpr (8, 0, 0, v9), /* wrpr ...,%pil  */
+wrpr (9, 0, 0, v9), /* wrpr ...,%cwp  */
+wrpr (10, 0, 0, v9), /* wrpr ...,%cansave  */
+wrpr (11, 0, 0, v9), /* wrpr ...,%canrestore  */
+wrpr (12, 0, 0, v9), /* wrpr ...,%cleanwin  */
+wrpr (13, 0, 0, v9), /* wrpr ...,%otherwin  */
+wrpr (14, 0, 0, v9), /* wrpr ...,%wstate  */
+wrpr (15, 0, 0, v9), /* wrpr ...,%fq  */
+wrpr (16, 0, 0, v9), /* wrpr ...,%gl  */
+wrpr (23, 0, HWCAP2_SPARC5, v9m), /* wdpr ...,%pmcdper  */
+wrpr (31, 0, 0, v9), /* wrpr ...,%ver */
+
+/* Instructions to read and write from/to hyperprivileged
+   registers.  */
+
+#define rdhpr(reg,hwcap,hwcap2,arch) \
+{ "rdhpr",	F3(2, 0x29, 0)|RS1((reg)),	F3(~2, ~0x29, ~0)|RS1(~(reg))|SIMM13(~0), "$,d", 0, (hwcap), (hwcap2), (arch) }
+
+rdhpr (0, HWCAP_VIS, 0, v9a), /* rdhpr %hpstate,r  */
+rdhpr (1, HWCAP_VIS, 0, v9a), /* rdhpr %htstate,r  */
+rdhpr (3, HWCAP_VIS, 0, v9a), /* rdhpr %hintp,r  */
+rdhpr (5, HWCAP_VIS, 0, v9a), /* rdhpr %htba,r  */
+rdhpr (6, HWCAP_VIS, 0, v9a), /* rdhpr %hver,r  */
+rdhpr (23, 0, HWCAP2_SPARC5, v9m), /* rdhpr %hmcdper,r  */
+rdhpr (24, 0, HWCAP2_SPARC5, v9m), /* rdhpr %hmcddfr,r  */
+rdhpr (27, 0, HWCAP2_SPARC5, v9m), /* rdhpr %hva_mask_nz,r  */
+rdhpr (28, HWCAP_VIS, 0, v9a), /* rdhpr %hstick_offset,r  */
+rdhpr (29, HWCAP_VIS, 0, v9a), /* rdhpar %hstick_enable,r  */
+rdhpr (31, HWCAP_VIS, 0, v9a), /* rdhpr %hstick_cmpr,r  */
+
+#define wrhpr(reg,hwcap,hwcap2,arch) \
+{ "wrhpr", F3(2, 0x33, 0)|RD((reg)), F3(~2, ~0x33, ~0)|RD(~(reg)),"1,2,%", 0, (hwcap), (hwcap2), (arch) }, /* wrhpr r1,r2,%hpriv */ \
+{ "wrhpr", F3(2, 0x33, 0)|RD((reg)), F3(~2, ~0x33, ~0)|RD(~(reg))|SIMM13(~0), "1,%", 0, (hwcap), (hwcap2), (arch) }, /* wrhpr r1,%hpriv */ \
+{ "wrhpr", F3(2, 0x33, 1)|RD((reg)), F3(~2, ~0x33, ~1)|RD(~(reg)), "1,i,%", 0, (hwcap), (hwcap2), (arch) }, /* wrhpr r1,i,%hpriv */  \
+{ "wrhpr", F3(2, 0x33, 1)|RD((reg)), F3(~2, ~0x33, ~1)|RD(~(reg)), "i,1,%", F_ALIAS, (hwcap), (hwcap2), (arch)  }, /* wrhpr i,r1,%hpriv */ \
+{ "wrhpr", F3(2, 0x33, 1)|RD((reg)), F3(~2, ~0x33, ~1)|RD(~(reg))|RS1(~0), "i,%", 0, (hwcap), (hwcap2), (arch) } /* wrhpr i,%hpriv */
+
+wrhpr (0,  HWCAP_VIS, 0, v9a), /* wrhpr ...,%hpstate  */
+wrhpr (1,  HWCAP_VIS, 0, v9a), /* wrhpr ...,%htstate  */
+wrhpr (3,  HWCAP_VIS, 0, v9a), /* wrhpr ...,%hintp  */
+wrhpr (5,  HWCAP_VIS, 0, v9a), /* wrhpr ...,%htba  */
+wrhpr (23, 0, HWCAP2_SPARC5, v9m), /* wrhpr ...,%hmcdper  */
+wrhpr (24, 0, HWCAP2_SPARC5, v9m), /* wrhpr ...,%hmcddfr  */
+wrhpr (27, 0, HWCAP2_SPARC5, v9m), /* wrhpr ...,%hva_mask_nz  */
+wrhpr (28, HWCAP_VIS, 0, v9a), /* wrhpr ...,%hstick_offset  */
+wrhpr (29, HWCAP_VIS, 0, v9a), /* wrhpr ...,%hstick_enable  */
+wrhpr (31, HWCAP_VIS, 0, v9a), /* wrhpr ...,%hstick_cmpr  */
 
 { "mov",	F3(2, 0x28, 0), F3(~2, ~0x28, ~0)|SIMM13(~0),		"M,d", F_ALIAS, 0, 0, v8 }, /* rd %asr1,r */
 { "mov",	F3(2, 0x28, 0), F3(~2, ~0x28, ~0)|RS1_G0|SIMM13(~0),	"y,d", F_ALIAS, 0, 0, v6 }, /* rd %y,r */
-- 
2.3.4



More information about the Binutils mailing list