This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH]: Add support for all new UA2005 instructions
- From: "David S. Miller" <davem at davemloft dot net>
- To: binutils at sources dot redhat dot com
- Date: Fri, 24 Feb 2006 17:39:07 -0800 (PST)
- Subject: [PATCH]: Add support for all new UA2005 instructions
This patch, which I just checked in, adds support for all of the new
v9 instructions and register encodings defined in the UA2005
architecture specification.
While I was adding new tests I also adds some tests for existing
window handling instructions which did not have tests.
opcodes/
2006-02-24 David S. Miller <davem@sunset.davemloft.net>
* sparc-dis.c (v9_priv_reg_names): Add "gl" entry.
(v9_hpriv_reg_names): New table.
(print_insn_sparc): Allow values up to 16 for '?' and '!'.
New cases '$' and '%' for read/write hyperprivileged register.
* sparc-opc.c (sparc_opcodes): Add new entries for UA2005
window handling and rdhpr/wrhpr instructions.
--- ./opcodes/sparc-dis.c.~1~ 2005-10-08 21:37:25.000000000 -0700
+++ ./opcodes/sparc-dis.c 2006-02-24 16:51:04.000000000 -0800
@@ -85,11 +85,22 @@ static char *v9_priv_reg_names[] =
{
"tpc", "tnpc", "tstate", "tt", "tick", "tba", "pstate", "tl",
"pil", "cwp", "cansave", "canrestore", "cleanwin", "otherwin",
- "wstate", "fq"
+ "wstate", "fq", "gl"
/* "ver" - special cased */
};
/* These are ordered according to there register number in
+ rdhpr and wrhpr insns. */
+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",
+ "resv28", "resv29", "resv30", "hstick_cmpr"
+};
+
+/* These are ordered according to there register number in
rd and wr insns (-16). */
static char *v9a_asr_reg_names[] =
{
@@ -768,7 +779,7 @@ print_insn_sparc (bfd_vma memaddr, disas
case '?':
if (X_RS1 (insn) == 31)
(*info->fprintf_func) (stream, "%%ver");
- else if ((unsigned) X_RS1 (insn) < 16)
+ else if ((unsigned) X_RS1 (insn) < 17)
(*info->fprintf_func) (stream, "%%%s",
v9_priv_reg_names[X_RS1 (insn)]);
else
@@ -776,13 +787,29 @@ print_insn_sparc (bfd_vma memaddr, disas
break;
case '!':
- if ((unsigned) X_RD (insn) < 15)
+ if ((unsigned) X_RD (insn) < 17)
(*info->fprintf_func) (stream, "%%%s",
v9_priv_reg_names[X_RD (insn)]);
else
(*info->fprintf_func) (stream, "%%reserved");
break;
+ case '$':
+ if ((unsigned) X_RS1 (insn) < 32)
+ (*info->fprintf_func) (stream, "%%%s",
+ v9_hpriv_reg_names[X_RS1 (insn)]);
+ else
+ (*info->fprintf_func) (stream, "%%reserved");
+ break;
+
+ case '%':
+ if ((unsigned) X_RD (insn) < 32)
+ (*info->fprintf_func) (stream, "%%%s",
+ v9_hpriv_reg_names[X_RD (insn)]);
+ else
+ (*info->fprintf_func) (stream, "%%reserved");
+ break;
+
case '/':
if (X_RS1 (insn) < 16 || X_RS1 (insn) > 25)
(*info->fprintf_func) (stream, "%%reserved");
--- ./opcodes/sparc-opc.c.~1~ 2005-10-08 21:37:25.000000000 -0700
+++ ./opcodes/sparc-opc.c 2006-02-24 17:08:14.000000000 -0800
@@ -692,6 +692,10 @@ const struct sparc_opcode sparc_opcodes[
{ "retry", F3(2, 0x3e, 0)|RD(1), F3(~2, ~0x3e, ~0)|RD(~1)|RS1_G0|SIMM13(~0), "", 0, v9 },
{ "saved", F3(2, 0x31, 0)|RD(0), F3(~2, ~0x31, ~0)|RD(~0)|RS1_G0|SIMM13(~0), "", 0, v9 },
{ "restored", F3(2, 0x31, 0)|RD(1), F3(~2, ~0x31, ~0)|RD(~1)|RS1_G0|SIMM13(~0), "", 0, v9 },
+{ "allclean", F3(2, 0x31, 0)|RD(2), F3(~2, ~0x31, ~0)|RD(~2)|RS1_G0|SIMM13(~0), "", 0, v9 },
+{ "otherw", F3(2, 0x31, 0)|RD(3), F3(~2, ~0x31, ~0)|RD(~3)|RS1_G0|SIMM13(~0), "", 0, v9 },
+{ "normalw", F3(2, 0x31, 0)|RD(4), F3(~2, ~0x31, ~0)|RD(~4)|RS1_G0|SIMM13(~0), "", 0, v9 },
+{ "invalw", F3(2, 0x31, 0)|RD(5), F3(~2, ~0x31, ~0)|RD(~5)|RS1_G0|SIMM13(~0), "", 0, v9 },
{ "sir", F3(2, 0x30, 1)|RD(0xf), F3(~2, ~0x30, ~1)|RD(~0xf)|RS1_G0, "i", 0, v9 },
{ "flush", F3(2, 0x3b, 0), F3(~2, ~0x3b, ~0)|ASI(~0), "1+2", 0, v8 },
@@ -878,6 +882,13 @@ const struct sparc_opcode sparc_opcodes[
{ "wrpr", F3(2, 0x32, 1), F3(~2, ~0x32, ~1), "i,1,!", F_ALIAS, v9 }, /* wrpr i,r1,%priv */
{ "wrpr", F3(2, 0x32, 1), F3(~2, ~0x32, ~1)|RS1(~0), "i,!", 0, v9 }, /* wrpr i,%priv */
+{ "rdhpr", F3(2, 0x29, 0), F3(~2, ~0x29, ~0)|SIMM13(~0), "$,d", 0, v9 }, /* rdhpr %hpriv,r */
+{ "wrhpr", F3(2, 0x33, 0), F3(~2, ~0x33, ~0), "1,2,%", 0, v9 }, /* wrhpr r1,r2,%hpriv */
+{ "wrhpr", F3(2, 0x33, 0), F3(~2, ~0x33, ~0)|SIMM13(~0), "1,%", 0, v9 }, /* wrhpr r1,%hpriv */
+{ "wrhpr", F3(2, 0x33, 1), F3(~2, ~0x33, ~1), "1,i,%", 0, v9 }, /* wrhpr r1,i,%hpriv */
+{ "wrhpr", F3(2, 0x33, 1), F3(~2, ~0x33, ~1), "i,1,%", F_ALIAS, v9 }, /* wrhpr i,r1,%hpriv */
+{ "wrhpr", F3(2, 0x33, 1), F3(~2, ~0x33, ~1)|RS1(~0), "i,%", 0, v9 }, /* wrhpr i,%hpriv */
+
/* ??? This group seems wrong. A three operand move? */
{ "mov", F3(2, 0x30, 0), F3(~2, ~0x30, ~0)|ASI(~0), "1,2,m", F_ALIAS, v8 }, /* wr r,r,%asrX */
{ "mov", F3(2, 0x30, 1), F3(~2, ~0x30, ~1), "1,i,m", F_ALIAS, v8 }, /* wr r,i,%asrX */
gas/
2006-02-24 David S. Miller <davem@sunset.davemloft.net>
* config/tc-sparc.c (priv_reg_table): Add entry for "gl".
(hpriv_reg_table): New table for hyperprivileged registers.
(sparc_ip): New cases '$' and '%' for wrhpr/rdhpr hyperprivileged
register encoding.
--- ./gas/config/tc-sparc.c.~1~ 2005-11-08 10:27:40.000000000 -0800
+++ ./gas/config/tc-sparc.c 2006-02-24 16:48:32.000000000 -0800
@@ -724,7 +724,7 @@ struct
{NULL, NULL, NULL},
};
-/* sparc64 privileged registers. */
+/* sparc64 privileged and hyperprivileged registers. */
struct priv_reg_entry
{
@@ -750,10 +750,22 @@ struct priv_reg_entry priv_reg_table[] =
{"otherwin", 13},
{"wstate", 14},
{"fq", 15},
+ {"gl", 16},
{"ver", 31},
{"", -1}, /* End marker. */
};
+struct priv_reg_entry hpriv_reg_table[] =
+{
+ {"hpstate", 0},
+ {"htstate", 1},
+ {"hintp", 3},
+ {"htba", 5},
+ {"hver", 6},
+ {"hstick_cmpr", 31},
+ {"", -1}, /* End marker. */
+};
+
/* v9a specific asrs. */
struct priv_reg_entry v9a_asr_table[] =
@@ -1572,6 +1584,42 @@ sparc_ip (str, pinsn)
goto error;
}
+ case '$':
+ case '%':
+ /* Parse a sparc64 hyperprivileged register. */
+ if (*s == '%')
+ {
+ struct priv_reg_entry *p = hpriv_reg_table;
+ unsigned int len = 9999999; /* Init to make gcc happy. */
+
+ s += 1;
+ while (p->name[0] > s[0])
+ p++;
+ while (p->name[0] == s[0])
+ {
+ len = strlen (p->name);
+ if (strncmp (p->name, s, len) == 0)
+ break;
+ p++;
+ }
+ if (p->name[0] != s[0])
+ {
+ error_message = _(": unrecognizable hyperprivileged register");
+ goto error;
+ }
+ if (*args == '$')
+ opcode |= (p->regnum << 14);
+ else
+ opcode |= (p->regnum << 25);
+ s += len;
+ continue;
+ }
+ else
+ {
+ error_message = _(": unrecognizable hyperprivileged register");
+ goto error;
+ }
+
case '_':
case '/':
/* Parse a v9a/v9b ancillary state register. */
gas/testsuite/
2006-02-24 David S. Miller <davem@sunset.davemloft.net>
* gas/sparc/rdhpr.s: New test.
* gas/sparc/rdhpr.d: New test.
* gas/sparc/wrhpr.s: New test.
* gas/sparc/wrhpr.d: New test.
* gas/sparc/window.s: New test.
* gas/sparc/window.d: New test.
* gas/sparc/rdpr.s: Add case for reading %gl register.
* gas/sparc/rdpr.d: Likewise.
* gas/sparc/wrpr.s: Add case for writing %gl register.
* gas/sparc/wrpr.d: Likewise.
* gas/sparc/sparc.exp: Update for new tests.
--- ./gas/testsuite/gas/sparc/rdhpr.s.~1~ 2006-02-24 16:26:27.000000000 -0800
+++ ./gas/testsuite/gas/sparc/rdhpr.s 2006-02-24 16:30:32.000000000 -0800
@@ -0,0 +1,8 @@
+# Test rdpr
+ .text
+ rdhpr %hpstate,%g1
+ rdhpr %htstate,%g2
+ rdhpr %hintp,%g3
+ rdhpr %htba,%g4
+ rdhpr %hver,%g5
+ rdhpr %hstick_cmpr,%g6
--- ./gas/testsuite/gas/sparc/rdhpr.d.~1~ 2006-02-24 16:26:33.000000000 -0800
+++ ./gas/testsuite/gas/sparc/rdhpr.d 2006-02-24 16:50:00.000000000 -0800
@@ -0,0 +1,15 @@
+#as: -64 -Av9
+#objdump: -dr
+#name: sparc64 rdhpr
+
+.*: +file format .*sparc.*
+
+Disassembly of section .text:
+
+0+ <.text>:
+ 0: 83 48 00 00 rdhpr %hpstate, %g1
+ 4: 85 48 40 00 rdhpr %htstate, %g2
+ 8: 87 48 c0 00 rdhpr %hintp, %g3
+ c: 89 49 40 00 rdhpr %htba, %g4
+ 10: 8b 49 80 00 rdhpr %hver, %g5
+ 14: 8d 4f c0 00 rdhpr %hstick_cmpr, %g6
--- ./gas/testsuite/gas/sparc/sparc.exp.~1~ 2004-05-11 20:06:10.000000000 -0700
+++ ./gas/testsuite/gas/sparc/sparc.exp 2006-02-24 17:09:21.000000000 -0800
@@ -40,7 +40,10 @@ if [istarget sparc*-*-*] {
run_dump_test "set64"
run_dump_test "synth64"
run_dump_test "rdpr"
+ run_dump_test "rdhpr"
run_dump_test "wrpr"
+ run_dump_test "wrhpr"
+ run_dump_test "window"
run_dump_test "reloc64"
run_dump_test "pcrel64"
run_dump_test "plt64"
--- ./gas/testsuite/gas/sparc/rdpr.s.~1~ 1999-05-03 00:28:52.000000000 -0700
+++ ./gas/testsuite/gas/sparc/rdpr.s 2006-02-24 16:56:00.000000000 -0800
@@ -16,4 +16,5 @@
rdpr %otherwin,%o6
rdpr %wstate,%o7
rdpr %fq,%l0
- rdpr %ver,%l1
+ rdpr %gl,%l1
+ rdpr %ver,%l2
--- ./gas/testsuite/gas/sparc/rdpr.d.~1~ 1999-06-10 14:08:03.000000000 -0700
+++ ./gas/testsuite/gas/sparc/rdpr.d 2006-02-24 16:57:59.000000000 -0800
@@ -23,4 +23,5 @@ Disassembly of section .text:
34: 9d 53 40 00 rdpr %otherwin, %sp
38: 9f 53 80 00 rdpr %wstate, %o7
3c: a1 53 c0 00 rdpr %fq, %l0
- 40: a3 57 c0 00 rdpr %ver, %l1
+ 40: a3 54 00 00 rdpr %gl, %l1
+ 44: a5 57 c0 00 rdpr %ver, %l2
--- ./gas/testsuite/gas/sparc/wrpr.s.~1~ 1999-05-03 00:28:52.000000000 -0700
+++ ./gas/testsuite/gas/sparc/wrpr.s 2006-02-24 16:57:17.000000000 -0800
@@ -15,3 +15,4 @@
wrpr %o5,%cleanwin
wrpr %o6,%otherwin
wrpr %o7,%wstate
+ wrpr %l0,%gl
--- ./gas/testsuite/gas/sparc/wrpr.d.~1~ 1999-06-10 14:08:10.000000000 -0700
+++ ./gas/testsuite/gas/sparc/wrpr.d 2006-02-24 16:57:53.000000000 -0800
@@ -22,3 +22,4 @@ Disassembly of section .text:
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
--- ./gas/testsuite/gas/sparc/wrhpr.s.~1~ 2006-02-24 16:58:58.000000000 -0800
+++ ./gas/testsuite/gas/sparc/wrhpr.s 2006-02-24 17:00:09.000000000 -0800
@@ -0,0 +1,7 @@
+# Test wrpr
+ .text
+ wrhpr %g1,%hpstate
+ wrhpr %g2,%htstate
+ wrhpr %g3,%hintp
+ wrhpr %g4,%htba
+ wrhpr %g5,%hstick_cmpr
--- ./gas/testsuite/gas/sparc/wrhpr.d.~1~ 2006-02-24 16:59:03.000000000 -0800
+++ ./gas/testsuite/gas/sparc/wrhpr.d 2006-02-24 17:01:06.000000000 -0800
@@ -0,0 +1,14 @@
+#as: -64 -Av9
+#objdump: -dr
+#name: sparc64 wrhpr
+
+.*: +file format .*sparc.*
+
+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: bf 99 40 00 wrhpr %g5, %hstick_cmpr
--- ./gas/testsuite/gas/sparc/window.s.~1~ 2006-02-24 17:09:12.000000000 -0800
+++ ./gas/testsuite/gas/sparc/window.s 2006-02-24 17:10:14.000000000 -0800
@@ -0,0 +1,8 @@
+# Test window
+ .text
+ saved
+ restored
+ allclean
+ otherw
+ normalw
+ invalw
--- ./gas/testsuite/gas/sparc/window.d.~1~ 2006-02-24 17:09:14.000000000 -0800
+++ ./gas/testsuite/gas/sparc/window.d 2006-02-24 17:15:15.000000000 -0800
@@ -0,0 +1,15 @@
+#as: -64 -Av9
+#objdump: -dr
+#name: sparc64 window
+
+.*: +file format .*sparc.*
+
+Disassembly of section .text:
+
+0+ <.text>:
+ 0: 81 88 00 00 saved
+ 4: 83 88 00 00 restored
+ 8: 85 88 00 00 allclean
+ c: 87 88 00 00 otherw
+ 10: 89 88 00 00 normalw
+ 14: 8b 88 00 00 invalw