Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/alpha/alpha Allow alpha_print_instruction() to be c...



details:   https://anonhg.NetBSD.org/src/rev/2f2660cb2979
branches:  trunk
changeset: 984071:2f2660cb2979
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Mon Jun 21 02:01:13 2021 +0000

description:
Allow alpha_print_instruction() to be called from outside DDB, and
allow the caller to supply a buffer to contain the pretty-printed
insn string, rather than db_printf() (which is used if there is no
supplied buffer).

diffstat:

 sys/arch/alpha/alpha/db_disasm.c      |  221 +++++++++++++++++++--------------
 sys/arch/alpha/alpha/db_instruction.h |   16 ++-
 2 files changed, 144 insertions(+), 93 deletions(-)

diffs (truncated from 431 to 300 lines):

diff -r e5a0edde12ba -r 2f2660cb2979 sys/arch/alpha/alpha/db_disasm.c
--- a/sys/arch/alpha/alpha/db_disasm.c  Sun Jun 20 20:59:08 2021 +0000
+++ b/sys/arch/alpha/alpha/db_disasm.c  Mon Jun 21 02:01:13 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: db_disasm.c,v 1.16 2014/03/20 20:51:40 christos Exp $ */
+/* $NetBSD: db_disasm.c,v 1.17 2021/06/21 02:01:13 thorpej Exp $ */
 
 /*
  * Mach Operating System
@@ -48,7 +48,7 @@
 
 #include <sys/cdefs.h>                 /* RCS ID & Copyright macro defns */
 
-__KERNEL_RCSID(0, "$NetBSD: db_disasm.c,v 1.16 2014/03/20 20:51:40 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: db_disasm.c,v 1.17 2021/06/21 02:01:13 thorpej Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -781,31 +781,47 @@
        "t10",  "t11",  "ra",   "pv",   "at",   "gp",   "sp",   "zero"
 };
 
-static int regcount;           /* how many regs used in this inst */
-static int regnum[3];          /* which regs used in this inst */
-
 static const char *
-register_name(int ireg)
+register_name(struct alpha_print_instruction_context *ctx, int ireg)
 {
        int     i;
 
-       for (i = 0; i < regcount; i++)
-               if (regnum[i] == ireg)
+       for (i = 0; i < ctx->regcount; i++)
+               if (ctx->regnum[i] == ireg)
                        break;
-       if (i >= regcount)
-               regnum[regcount++] = ireg;
+       if (i >= ctx->regcount)
+               ctx->regnum[ctx->regcount++] = ireg;
        return (name_of_register[ireg]);
 }
 
+static void
+insn_printf(struct alpha_print_instruction_context *ctx,
+    const char *fmt, ...)
+{
+       va_list ap;
+
+       va_start(ap, fmt);
+
+       if (ctx->buf != NULL) {
+               if (ctx->cursor < ctx->bufsize) {
+                       ctx->cursor += vsnprintf(ctx->buf + ctx->cursor,
+                           ctx->bufsize - ctx->cursor, fmt, ap);
+               }
+       } else {
+               db_vprintf(fmt, ap);
+       }
+
+       va_end(ap);
+}
+
 /*
  * Disassemble instruction at 'loc'.  'altfmt' specifies an
  * (optional) alternate format.  Return address of start of
  * next instruction.
  */
 
-static int
-alpha_print_instruction(db_addr_t iadr, alpha_instruction i,
-    bool showregs)
+int
+alpha_print_instruction(struct alpha_print_instruction_context *ctx)
 {
        const char      *opcode;
        int             ireg;
@@ -813,18 +829,19 @@
        bool            fstore;
        pal_instruction p;
 
-       regcount = 0;
+       ctx->regcount = 0;
        fstore = false;
-       opcode = op_name[i.mem_format.opcode];
+       opcode = op_name[ctx->insn.mem_format.opcode];
 
        /*
         *      Dispatch directly on the opcode, save code
         *      duplication sometimes via "harmless gotos".
         */
-       switch (i.mem_format.opcode) {
+       switch (ctx->insn.mem_format.opcode) {
        case op_pal:
                /* "call_pal" is a long string; just use a space. */
-               db_printf("%s %s", opcode, pal_opname(i.pal_format.function));
+               insn_printf(ctx, "%s %s", opcode,
+                   pal_opname(ctx->insn.pal_format.function));
                break;
        case op_lda:
        case op_ldah:
@@ -846,49 +863,54 @@
                 * For this and the following three groups we
                 * just need different opcode strings
                 */
-               opcode = arit_name(i.operate_lit_format.function);
+               opcode = arit_name(ctx->insn.operate_lit_format.function);
                goto operate;
                break;
        case op_logical:
-               opcode = logical_name(i.operate_lit_format.function);
+               opcode = logical_name(ctx->insn.operate_lit_format.function);
                goto operate;
                break;
        case op_bit:
-               opcode = bitop_name(i.operate_lit_format.function);
+               opcode = bitop_name(ctx->insn.operate_lit_format.function);
                goto operate;
                break;
        case op_mul:
-               opcode = mul_name(i.operate_lit_format.function);
+               opcode = mul_name(ctx->insn.operate_lit_format.function);
 operate:
                /*
                 * Nice and uniform, just check for literals
                 */
-               db_printf("%s\t%s,", opcode,
-                   register_name(i.operate_lit_format.ra));
-               if (i.operate_lit_format.one)
-                       db_printf("#0x%x", i.operate_lit_format.literal);
-               else
-                       db_printf("%s", register_name(i.operate_reg_format.rb));
-               db_printf(",%s", register_name(i.operate_lit_format.rc));
+               insn_printf(ctx, "%s\t%s,", opcode,
+                   register_name(ctx, ctx->insn.operate_lit_format.ra));
+               if (ctx->insn.operate_lit_format.one) {
+                       insn_printf(ctx, "#0x%x",
+                           ctx->insn.operate_lit_format.literal);
+               } else {
+                       insn_printf(ctx, "%s",
+                           register_name(ctx,
+                                         ctx->insn.operate_reg_format.rb));
+               }
+               insn_printf(ctx, ",%s",
+                   register_name(ctx, ctx->insn.operate_lit_format.rc));
                break;
        case op_vax_float:
                /*
                 * The three floating point groups are even simpler
                 */
-               opcode = vaxf_name(i.float_format.function);
+               opcode = vaxf_name(ctx->insn.float_format.function);
                goto foperate;
                break;
        case op_ieee_float:
-               opcode = ieeef_name(i.float_format.function);
+               opcode = ieeef_name(ctx->insn.float_format.function);
                goto foperate;
                break;
        case op_any_float:
-               opcode = anyf_name(i.float_format.function);
+               opcode = anyf_name(ctx->insn.float_format.function);
 foperate:
-               db_printf("%s\tf%d,f%d,f%d", opcode,
-                       i.float_format.fa,
-                       i.float_format.fb,
-                       i.float_format.fc);
+               insn_printf(ctx, "%s\tf%d,f%d,f%d", opcode,
+                       ctx->insn.float_format.fa,
+                       ctx->insn.float_format.fb,
+                       ctx->insn.float_format.fc);
                break;
        case op_special:
                /*
@@ -897,27 +919,30 @@
                {
                        register unsigned int code;
 
-                       code = (i.mem_format.displacement)&0xffff;
+                       code = (ctx->insn.mem_format.displacement)&0xffff;
                        opcode = special_name(code);
 
                        switch (code) {
                        case op_ecb:
-                               db_printf("%s\t(%s)", opcode,
-                                       register_name(i.mem_format.rb));
+                               insn_printf(ctx, "%s\t(%s)", opcode,
+                                   register_name(ctx,
+                                                 ctx->insn.mem_format.rb));
                                break;
                        case op_fetch:
                        case op_fetch_m:
-                               db_printf("%s\t0(%s)", opcode,
-                                       register_name(i.mem_format.rb));
+                               insn_printf(ctx, "%s\t0(%s)", opcode,
+                                   register_name(ctx,
+                                                 ctx->insn.mem_format.rb));
                                break;
                        case op_rpcc:
                        case op_rc:
                        case op_rs:
-                               db_printf("%s\t%s", opcode,
-                                       register_name(i.mem_format.ra));
+                               insn_printf(ctx, "%s\t%s", opcode,
+                                   register_name(ctx,
+                                                 ctx->insn.mem_format.ra));
                                break;
                        default:
-                               db_printf("%s", opcode);
+                               insn_printf(ctx, "%s", opcode);
                        break;
                        }
                }
@@ -927,21 +952,21 @@
                 * Jump instructions really are of two sorts,
                 * depending on the use of the hint info.
                 */
-               opcode = jump_name(i.jump_format.action);
-               switch (i.jump_format.action) {
+               opcode = jump_name(ctx->insn.jump_format.action);
+               switch (ctx->insn.jump_format.action) {
                case op_jmp:
                case op_jsr:
-                       db_printf("%s\t%s,(%s),", opcode,
-                               register_name(i.jump_format.ra),
-                               register_name(i.jump_format.rb));
-                       signed_immediate = i.jump_format.hint;
+                       insn_printf(ctx, "%s\t%s,(%s),", opcode,
+                           register_name(ctx, ctx->insn.jump_format.ra),
+                           register_name(ctx, ctx->insn.jump_format.rb));
+                       signed_immediate = ctx->insn.jump_format.hint;
                        goto branch_displacement;
                        break;
                case op_ret:
                case op_jcr:
-                       db_printf("%s\t%s,(%s)", opcode,
-                               register_name(i.jump_format.ra),
-                               register_name(i.jump_format.rb));
+                       insn_printf(ctx, "%s\t%s,(%s)", opcode,
+                           register_name(ctx, ctx->insn.jump_format.ra),
+                           register_name(ctx, ctx->insn.jump_format.rb));
                        break;
                }
                break;
@@ -949,30 +974,30 @@
                /*
                 * These are just in "operate" format.
                 */
-               opcode = intmisc_name(i.operate_lit_format.function);
+               opcode = intmisc_name(ctx->insn.operate_lit_format.function);
                goto operate;
                break;
                        /* HW instructions, possibly chip-specific XXXX */
        case op_pal19:  /* "hw_mfpr" */
        case op_pal1d:  /* "hw_mtpr" */
-               p.bits = i.bits;
-               db_printf("\t%s%s\t%s, %d", opcode,
+               p.bits = ctx->insn.bits;
+               insn_printf(ctx, "\t%s%s\t%s, %d", opcode,
                        mXpr_name[p.mXpr_format.regset],
-                       register_name(p.mXpr_format.rd),
+                       register_name(ctx, p.mXpr_format.rd),
                        p.mXpr_format.index);
                break;
        case op_pal1b:  /* "hw_ld" */
        case op_pal1f:  /* "hw_st" */
-               p.bits = i.bits;
-               db_printf("\t%s%c%s\t%s,", opcode,
+               p.bits = ctx->insn.bits;
+               insn_printf(ctx, "\t%s%c%s\t%s,", opcode,
                        (p.mem_format.qw) ? 'q' : 'l',
                        hwlds_name[p.mem_format.qualif],
-                       register_name(p.mem_format.rd));
+                       register_name(ctx, p.mem_format.rd));
                signed_immediate = (long)p.mem_format.displacement;
                goto loadstore_address;
 
        case op_pal1e:  /* "hw_rei" */
-               db_printf("\t%s", opcode);
+               insn_printf(ctx, "\t%s", opcode);
                break;
 
        case op_ldf:
@@ -997,28 +1022,31 @@
                 * Memory operations, including floats
                 */
 loadstore:
-               if (fstore)
-                   db_printf("%s\tf%d,", opcode, i.mem_format.ra);
-               else
-                   db_printf("%s\t%s,", opcode,
-                       register_name(i.mem_format.ra));
-               signed_immediate = (long)i.mem_format.displacement;
+               if (fstore) {
+                       insn_printf(ctx, "%s\tf%d,", opcode,
+                           ctx->insn.mem_format.ra);
+               } else {
+                       insn_printf(ctx, "%s\t%s,", opcode,
+                           register_name(ctx, ctx->insn.mem_format.ra));
+               }



Home | Main Index | Thread Index | Old Index