summaryrefslogtreecommitdiff
path: root/opcodes
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2004-10-07 14:18:17 +0000
committerNick Clifton <nickc@redhat.com>2004-10-07 14:18:17 +0000
commit2b9d11255242b1e1bc84563fa36415db51ca6349 (patch)
tree9b8753ea438eceaa92d489ea0f9681f7798a4958 /opcodes
parentf47da9a7c0d4f5ca0ef6d748e3508d93a0809ba9 (diff)
downloadbinutils-redhat-2b9d11255242b1e1bc84563fa36415db51ca6349.tar.gz
Add support for CRX co-processor opcodes
Diffstat (limited to 'opcodes')
-rw-r--r--opcodes/ChangeLog9
-rw-r--r--opcodes/crx-dis.c73
-rw-r--r--opcodes/crx-opc.c56
3 files changed, 96 insertions, 42 deletions
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index 342c2f3484..11b8a95706 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,3 +1,12 @@
+2004-10-07 Tomer Levi <Tomer.Levi@nsc.com>
+
+ * crx-opc.c (crx_instruction): Support Co-processor insns.
+ * crx-dis.c (COP_ARG_TYPE): New enum for CO-Processor arguments.
+ (getregliststring): Change function to use the above enum.
+ (print_arg): Handle CO-Processor insns.
+ (crx_cinvs): Add 'b' option to invalidate the branch-target
+ cache.
+
2004-10-06 Aldy Hernandez <aldyh@redhat.com>
* ppc-opc.c (powerpc_opcodes): Add efscfd, efdabs, efdnabs,
diff --git a/opcodes/crx-dis.c b/opcodes/crx-dis.c
index 5796a2ef08..b2cf31210f 100644
--- a/opcodes/crx-dis.c
+++ b/opcodes/crx-dis.c
@@ -59,10 +59,25 @@ cinv_entry;
/* CRX 'cinv' options. */
const cinv_entry crx_cinvs[] =
{
- {"[i]", 2}, {"[i,u]", 3}, {"[d]", 4},
- {"[d,u]", 5}, {"[d,i]", 6}, {"[d,i,u]", 7}
+ {"[i]", 2}, {"[i,u]", 3}, {"[d]", 4}, {"[d,u]", 5},
+ {"[d,i]", 6}, {"[d,i,u]", 7}, {"[b]", 8},
+ {"[b,i]", 10}, {"[b,i,u]", 11}, {"[b,d]", 12},
+ {"[b,d,u]", 13}, {"[b,d,i]", 14}, {"[b,d,i,u]", 15}
};
+/* Enum to distinguish CO-Processor [special] registers arguments
+ from general purpose regidters. */
+typedef enum COP_ARG_TYPE
+ {
+ /* Not a CO-Processor argument (probably a general purpose reg.). */
+ NO_COP_ARG = 0,
+ /* A CO-Processor argument (c<N>). */
+ COP_ARG,
+ /* A CO-Processor special argument (cs<N>). */
+ COPS_ARG
+ }
+COP_ARG_TYPE;
+
/* Number of valid 'cinv' instruction options. */
int NUMCINVS = ((sizeof crx_cinvs)/(sizeof crx_cinvs[0]));
/* Current opcode table entry we're disassembling. */
@@ -89,7 +104,7 @@ static char *getcopregname (copreg, reg_type);
static char * getprocregname (int);
static char *gettrapstring (unsigned);
static char *getcinvstring (unsigned);
-static void getregliststring (int, char *, int);
+static void getregliststring (int, char *, enum COP_ARG_TYPE);
static wordU get_word_at_PC (bfd_vma, struct disassemble_info *);
static void get_words_at_PC (bfd_vma, struct disassemble_info *);
static unsigned long build_mask (void);
@@ -225,7 +240,7 @@ powerof2 (int x)
/* Transform a register bit mask to a register list. */
void
-getregliststring (int trap, char *string, int core_cop)
+getregliststring (int trap, char *string, enum COP_ARG_TYPE core_cop)
{
char temp_string[5];
int i;
@@ -236,11 +251,21 @@ getregliststring (int trap, char *string, int core_cop)
for (i = 0; i < 16; i++)
{
if (trap & 0x1)
- {
- if (core_cop)
- sprintf (temp_string, "r%d", i);
- else
- sprintf (temp_string, "c%d", i);
+ {
+ switch (core_cop)
+ {
+ case NO_COP_ARG:
+ sprintf (temp_string, "r%d", i);
+ break;
+ case COP_ARG:
+ sprintf (temp_string, "c%d", i);
+ break;
+ case COPS_ARG:
+ sprintf (temp_string, "cs%d", i);
+ break;
+ default:
+ break;
+ }
strcat (string, temp_string);
if (trap & 0xfffe)
strcat (string, ",");
@@ -490,22 +515,26 @@ print_arg (argument *a, struct disassemble_info *info)
else if (INST_HAS_REG_LIST)
{
- if (!IS_INSN_TYPE (COP_REG_INS))
+ COP_ARG_TYPE cop_ins = IS_INSN_TYPE (COP_REG_INS) ?
+ COP_ARG : IS_INSN_TYPE (COPS_REG_INS) ?
+ COPS_ARG : NO_COP_ARG;
+
+ if (cop_ins != NO_COP_ARG)
+ {
+ /* Check for proper argument number. */
+ if (processing_argument_number == 2)
+ {
+ getregliststring (a->constant, string, cop_ins);
+ func (stream, "%s", string);
+ }
+ else
+ func (stream, "$0x%x", a->constant);
+ }
+ else
{
- getregliststring (a->constant, string, 1);
+ getregliststring (a->constant, string, cop_ins);
func (stream, "%s", string);
}
- else
- {
- /* Check for proper argument number. */
- if (processing_argument_number == 2)
- {
- getregliststring (a->constant, string, 0);
- func (stream, "%s", string);
- }
- else
- func (stream, "$0x%x", a->constant);
- }
}
else
func (stream, "$0x%x", a->constant);
diff --git a/opcodes/crx-opc.c b/opcodes/crx-opc.c
index b01addfa52..846b78c6c2 100644
--- a/opcodes/crx-opc.c
+++ b/opcodes/crx-opc.c
@@ -488,39 +488,55 @@ const inst crx_instruction[] =
BR_INST ("bal", 0x307, 0x317, 0),
- /* Decrement and Branch instructions */
+ /* Decrement and Branch instructions. */
BR_INST ("dbnzb", 0x304, 0x314, DCR_BRANCH_INS),
BR_INST ("dbnzw", 0x305, 0x315, DCR_BRANCH_INS),
BR_INST ("dbnzd", 0x306, 0x316, DCR_BRANCH_INS),
- /* Jump and link instructions */
+ /* Jump and link instructions. */
REG1_INST ("jal", 0xFF8),
REG2_INST ("jal", 0x37),
REG2_INST ("jalid", 0x33),
- /* opc12 c4 opc12 r mask16 */
- {"loadmcr", 3, 0x3110300, 4, COP_REG_INS | REG_LIST | FMT_5, {{i4,16}, {regr,0}, {i16,0}}},
- {"stormcr", 3, 0x3110301, 4, COP_REG_INS | REG_LIST | FMT_5, {{i4,16}, {regr,0}, {i16,0}}},
-
- /* esc16 r procreg */
- {"mtpr", 2, 0x3009, 16, 0, {{regr8,8}, {regr8,0}}},
- /* esc16 procreg r */
- {"mfpr", 2, 0x300A, 16, 0, {{regr8,8}, {regr8,0}}},
- /* opc12 c4 opc8 r copreg */
- {"mtcr", 2, 0x301030, 8, COP_REG_INS | FMT_2, {{i4,16}, {regr,4}, {copregr,0}}},
- /* opc12 c4 opc8 copreg r */
- {"mfcr", 2, 0x301031, 8, COP_REG_INS | FMT_2, {{i4,16}, {copregr,4}, {regr,0}}},
- /* opc12 c4 opc8 r copsreg */
- {"mtcsr", 2, 0x301032, 8, COP_REG_INS | FMT_2, {{i4,16}, {regr,4}, {copsregr,0}}},
- /* opc12 c4 opc8 copsreg r */
- {"mfcsr", 2, 0x301033, 8, COP_REG_INS | FMT_2, {{i4,16}, {copsregr,4}, {regr,0}}},
-
- /* CO-processor extensions */
+/* Create a CO-processor instruction. */
+#define COP_INST(NAME, OPC, TYPE, REG1, REG2) \
+ /* opc12 c4 opc8 REG1 REG2 */ \
+ {NAME, 2, 0x301030+OPC, 8, TYPE | FMT_2, {{i4,16}, {REG1,4}, {REG2,0}}}
+
+ COP_INST ("mtcr", 0, COP_REG_INS, regr, copregr),
+ COP_INST ("mfcr", 1, COP_REG_INS, copregr, regr),
+ COP_INST ("mtcsr", 2, COPS_REG_INS, regr, copsregr),
+ COP_INST ("mfcsr", 3, COPS_REG_INS, copsregr, regr),
+ COP_INST ("ldcr", 4, COP_REG_INS, regr, copregr),
+ COP_INST ("stcr", 5, COP_REG_INS, regr, copregr),
+ COP_INST ("ldcsr", 6, COPS_REG_INS, regr, copsregr),
+ COP_INST ("stcsr", 7, COPS_REG_INS, regr, copsregr),
+
+/* Create a memory-related CO-processor instruction. */
+#define COPMEM_INST(NAME, OPC, TYPE) \
+ /* opc12 c4 opc12 r mask16 */ \
+ {NAME, 3, 0x3110300+OPC, 4, TYPE | REG_LIST | FMT_5, {{i4,16}, {regr,0}, {i16,0}}}
+
+ COPMEM_INST("loadmcr", 0, COP_REG_INS),
+ COPMEM_INST("stormcr", 1, COP_REG_INS),
+ COPMEM_INST("loadmcsr", 2, COPS_REG_INS),
+ COPMEM_INST("stormcsr", 3, COPS_REG_INS),
+
+ /* CO-processor extensions. */
/* opc12 c4 opc4 i4 disps9 */
{"bcop", 2, 0x30107, 12, COP_BRANCH_INS | FMT_4, {{i4,16}, {i4,8}, {d9,0}}},
/* opc12 c4 opc4 i4 disps25 */
{"bcop", 3, 0x31107, 12, COP_BRANCH_INS | FMT_4, {{i4,16}, {i4,8}, {d25,0}}},
+ /* opc12 c4 opc4 cpdo r r */
+ {"cpdop", 2, 0x3010B, 12, COP_REG_INS | FMT_4, {{i4,16}, {i4,8}, {regr,4}, {regr,0}}},
+ /* opc12 c4 opc4 cpdo r r cpdo16 */
+ {"cpdop", 3, 0x3110B, 12, COP_REG_INS | FMT_4, {{i4,16}, {i4,8}, {regr,4}, {regr,0}, {i16,0}}},
+ /* esc16 r procreg */
+ {"mtpr", 2, 0x3009, 16, 0, {{regr8,8}, {regr8,0}}},
+ /* esc16 procreg r */
+ {"mfpr", 2, 0x300A, 16, 0, {{regr8,8}, {regr8,0}}},
+ /* Miscellaneous. */
/* opc12 i4 */
{"excp", 1, 0xFFF, 20, 0, {{i4,16}}},
/* opc28 i4 */