diff options
-rw-r--r-- | opcodes/ChangeLog | 9 | ||||
-rw-r--r-- | opcodes/sparc-dis.c | 33 | ||||
-rw-r--r-- | opcodes/sparc-opc.c | 11 |
3 files changed, 50 insertions, 3 deletions
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 4400057..d97df75 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,12 @@ +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. + 2006-02-24 DJ Delorie <dj@redhat.com> * m32c-desc.c: Regenerate with linker relaxation attributes. diff --git a/opcodes/sparc-dis.c b/opcodes/sparc-dis.c index cbc6d60..bfa7ea2 100644 --- a/opcodes/sparc-dis.c +++ b/opcodes/sparc-dis.c @@ -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, disassemble_info *info) 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, disassemble_info *info) 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"); diff --git a/opcodes/sparc-opc.c b/opcodes/sparc-opc.c index 21bfc7e..e23bbae 100644 --- a/opcodes/sparc-opc.c +++ b/opcodes/sparc-opc.c @@ -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 */ |