Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/sh5/sh5 Track adjacent movi/shori instructions with...
details: https://anonhg.NetBSD.org/src/rev/9c186217c3ba
branches: trunk
changeset: 535944:9c186217c3ba
user: scw <scw%NetBSD.org@localhost>
date: Sun Sep 01 22:39:56 2002 +0000
description:
Track adjacent movi/shori instructions with the same destination register
so we can print the accumulated value.
Print symbols, if possible, when decoding "pta" branch targets, and
"movi"/"shori" accumulated values.
diffstat:
sys/arch/sh5/sh5/db_disasm.c | 141 +++++++++++++++++++++++++++++++-----------
1 files changed, 104 insertions(+), 37 deletions(-)
diffs (263 lines):
diff -r c140513f375c -r 9c186217c3ba sys/arch/sh5/sh5/db_disasm.c
--- a/sys/arch/sh5/sh5/db_disasm.c Sun Sep 01 22:30:09 2002 +0000
+++ b/sys/arch/sh5/sh5/db_disasm.c Sun Sep 01 22:39:56 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: db_disasm.c,v 1.5 2002/09/01 10:07:25 scw Exp $ */
+/* $NetBSD: db_disasm.c,v 1.6 2002/09/01 22:39:56 scw Exp $ */
/*
* Copyright 2002 Wasabi Systems, Inc.
@@ -53,17 +53,18 @@
#include <ddb/ddbvar.h>
typedef u_int32_t opcode_t;
-typedef const char *(*format_func_t)(opcode_t, long, char *, char *, char *);
+typedef const char *(*format_func_t)(opcode_t, db_addr_t,
+ char *, char *, char *);
#define SH5_OPCODE_FORMAT(op) (((op) >> 26) & 0x3f)
/*
* Opcode Major Formats
*/
-static const char *sh5_fmt_mnd0(opcode_t, long, char *, char *, char *);
-static const char *sh5_fmt_msd6(opcode_t, long, char *, char *, char *);
-static const char *sh5_fmt_msd10(opcode_t, long, char *, char *, char *);
-static const char *sh5_fmt_xsd16(opcode_t, long, char *, char *, char *);
+static const char *sh5_fmt_mnd0(opcode_t, db_addr_t, char *, char *, char *);
+static const char *sh5_fmt_msd6(opcode_t, db_addr_t, char *, char *, char *);
+static const char *sh5_fmt_msd10(opcode_t, db_addr_t, char *, char *, char *);
+static const char *sh5_fmt_xsd16(opcode_t, db_addr_t, char *, char *, char *);
static const format_func_t major_format_funcs[] = {
/* Opcode bits 5, 4 and 3 == 000 */
@@ -1033,7 +1034,7 @@
char op_imm; /* Immediate operand */
char op_d; /* Destination operand */
};
-static int sh5_fmt_xsd16_decode_op(int, int, long, char *);
+static int sh5_fmt_xsd16_decode_op(int, int, int, db_addr_t, char *);
#define FMT_XSD16_MAJ_INDEX(op) (SH5_OPCODE_FORMAT(op) - 0x32)
#define FMT_XSD16_IMM(op) (((op) >> 10) & 0xffff)
@@ -1081,13 +1082,14 @@
static int sh5_sign_extend(int, int);
+static char oper1[128], oper2[128], oper3[128];
+static char extra_info[256];
db_addr_t
db_disasm(db_addr_t loc, boolean_t dummy)
{
format_func_t fp;
opcode_t op;
- char oper1[20], oper2[20], oper3[20];
const char *mnemonic, *comma = "";
if (loc < SH5_KSEG0_BASE) {
@@ -1099,6 +1101,8 @@
} else
op = *((opcode_t *)loc);
+ extra_info[0] = '\0';
+
/*
* The lowest 4 bits must be zero
*/
@@ -1129,14 +1133,17 @@
if (oper3[0])
db_printf("%s%s", comma, oper3);
- db_printf("\n");
+ if (extra_info[0] != '\0')
+ db_printf("\t%s\n", extra_info);
+ else
+ db_printf("\n");
return (loc + sizeof(opcode_t));
}
/*ARGSUSED*/
static const char *
-sh5_fmt_mnd0(opcode_t op, long loc, char *op1, char *op2, char *op3)
+sh5_fmt_mnd0(opcode_t op, db_addr_t loc, char *op1, char *op2, char *op3)
{
const struct format_mnd0 *fp;
static char trl[16];
@@ -1230,7 +1237,7 @@
/*ARGSUSED*/
static const char *
-sh5_fmt_msd6(opcode_t op, long loc, char *op1, char *op2, char *op3)
+sh5_fmt_msd6(opcode_t op, db_addr_t loc, char *op1, char *op2, char *op3)
{
const struct format_msd6 *fp;
static char trl[16];
@@ -1308,7 +1315,7 @@
/*ARGSUSED*/
static const char *
-sh5_fmt_msd10(opcode_t op, long loc, char *op1, char *op2, char *op3)
+sh5_fmt_msd10(opcode_t op, db_addr_t loc, char *op1, char *op2, char *op3)
{
const struct format_msd10 *fp;
int r, imm, sd;
@@ -1369,7 +1376,7 @@
}
static const char *
-sh5_fmt_xsd16(opcode_t op, long loc, char *op1, char *op2, char *op3)
+sh5_fmt_xsd16(opcode_t op, db_addr_t loc, char *op1, char *op2, char *op3)
{
const struct format_xsd16 *fp;
static char trl[16];
@@ -1383,10 +1390,10 @@
if (fp->mnemonic == NULL)
return (NULL);
- if (sh5_fmt_xsd16_decode_op(fp->op_imm, imm, loc, op1) < 0)
+ if (sh5_fmt_xsd16_decode_op(fp->op_imm, imm, d, loc, op1) < 0)
return (NULL);
- if (sh5_fmt_xsd16_decode_op(fp->op_d, d, 0, op2) < 0)
+ if (sh5_fmt_xsd16_decode_op(fp->op_d, d, 0, 0, op2) < 0)
return (NULL);
op3[0] = '\0';
@@ -1400,53 +1407,113 @@
}
static int
-sh5_fmt_xsd16_decode_op(int fmt, int op, long loc, char *ops)
+sh5_fmt_xsd16_decode_op(int fmt, int op, int d, db_addr_t loc, char *ops)
{
- char opstr[16];
+ char *symname;
+ db_sym_t sym;
+ db_expr_t diff;
+ opcode_t nextop;
+ char accmovi_str[32];
+ static db_addr_t last_movi;
+ static int last_d = -1;
+ static int64_t accmovi;
switch (fmt) {
case FMT_XSD16_OP_R:
- sprintf(opstr, "r%d", op);
+ sprintf(ops, "r%d", op);
break;
case FMT_XSD16_OP_TRL:
- if ((op & 0x18) != 0) {
- db_printf("xsd16: bad trl op: 0x%x\n", op);
+ if ((op & 0x18) != 0)
return (-1);
- }
- sprintf(opstr, "tr%d", op & 0x7);
+ sprintf(ops, "tr%d", op & 0x7);
break;
case FMT_XSD16_OP_SHORI:
- sprintf(opstr, "%d", op);
- /*
- * XXX: Should tie-in with a preceding MOVI to figure
- * XXX: out the 32/64-bit value and possibly lookup symbol.
- */
+ sprintf(ops, "%d", op);
+ if ((last_movi + 4) == loc && last_d == d) {
+ accmovi <<= 16;
+ accmovi |= op;
+
+ if ((loc + 4) < SH5_KSEG0_BASE)
+ nextop = fuword((void *)(loc + 4));
+ else
+ nextop = *((opcode_t *)(loc + 4));
+
+ if ((nextop & 0xfc00000f) == 0xc8000000 &&
+ ((nextop >> 4) & 0x3f) == d) {
+ last_movi = loc;
+ } else {
+ symname = NULL;
+ sym = db_search_symbol((db_addr_t)accmovi,
+ DB_STGY_PROC, &diff);
+ db_symbol_values(sym, &symname, NULL);
+
+ if (symname == NULL || symname[0] == '/') {
+ sym = db_search_symbol(
+ (db_addr_t)accmovi,
+ DB_STGY_XTRN, &diff);
+ db_symbol_values(sym, &symname, NULL);
+ if (symname && symname[0] == '/')
+ symname = NULL;
+ } else {
+ diff &= ~1;
+#ifdef _ILP32
+ accmovi &= 0xffffffff;
+#endif
+ }
+
+ if ((u_int64_t)accmovi >= 0x100000000) {
+ sprintf(accmovi_str, "0x%08x%08x",
+ (u_int)(accmovi >> 32),
+ (u_int)accmovi);
+ } else
+ sprintf(accmovi_str, "0x%08x",
+ (u_int)accmovi);
+
+ if (symname == NULL || diff >= 0x400000)
+ strcpy(extra_info, accmovi_str);
+ else {
+ if (diff)
+ sprintf(extra_info,
+ "%s <%s+0x%x>",
+ accmovi_str, symname, diff);
+ else
+ sprintf(extra_info, "%s <%s>",
+ accmovi_str, symname);
+ }
+ }
+ }
break;
case FMT_XSD16_OP_MOVI:
op = sh5_sign_extend(op, 16);
- sprintf(opstr, "%d", op);
- /*
- * XXX: Should tie-in with a subsequent SHORI insn(s).
- */
+ sprintf(ops, "%d", op);
+ last_movi = loc;
+ last_d = d;
+ accmovi = (int64_t)op;
break;
case FMT_XSD16_OP_LABEL:
op = sh5_sign_extend(op, 16) * 4;
- loc += op;
- sprintf(opstr, "0x%lx", loc);
- /*
- * XXX: Should look up the symbol
- */
+ loc = (long)loc + (long)op;
+ symname = NULL;
+ sym = db_search_symbol(loc, DB_STGY_PROC, &diff);
+ db_symbol_values(sym, &symname, NULL);
+ if (symname == NULL)
+ sprintf(ops, "0x%lx", loc);
+ else {
+ if (diff)
+ sprintf(ops, "%s+0x%x", symname, diff);
+ else
+ strcpy(ops, symname);
+ }
break;
default:
return (-1);
}
- strcpy(ops, opstr);
return (0);
}
Home |
Main Index |
Thread Index |
Old Index