kvisc/vm/pc/dump.c

161 lines
3.4 KiB
C

// The OS/K Team licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#include <pc/arch.h>
#define ABS(x) ((short)(x) < 0 ? -x : x)
char *cond_suffixes[] =
{
"-",
"c", "o", "z", "s", "p",
"be", "l", "le", "axz",
"bxz", "cxz",
"?"
};
void dump_acc(ctx_t *ctx, acc_t *p);
void dump_instr(ctx_t *ctx,
instr_t *in,
acc_t *p1,
acc_t *p2,
acc_t *p3,
bool lock,
bool rep)
{
uint cond = ctx->cond;
trace("0x%lX:\t", ctx->cur_pc);
if (lock)
trace("lock");
trace("%s", in->name);
if (rep)
trace(".rep");
if (cond)
{
trace(".");
if (cond & (1 << 4))
trace("n");
assert((cond & ~(1 << 4)) <= sizeof(cond_suffixes)/sizeof(char *));
trace("%s", cond_suffixes[cond & ~(1 << 4)]);
}
if (!rep && cond != ((1 << 4) | CD_CXZ))
trace("\t\t");
else
trace("\t");
if (p1)
dump_acc(ctx, p1);
if (p2) {
trace(", ");
dump_acc(ctx, p2);
}
if (p3) {
trace(", ");
dump_acc(ctx, p3);
}
trace("\n");
}
void dump_acc(ctx_t *ctx, acc_t *p)
{
uint mfmt;
sym_t *sym;
if (p->type == A_REG)
trace("%s", ctx->r[p->reg].name);
else if (p->type == A_IMM64)
{
if (p->val < 0xA) trace("%lu", p->val);
else trace("0x%lX", p->val);
}
else if (p->type == A_IMM32)
{
if (p->val < 0xA)
trace("%lu", p->val);
else
{
sym = find_sym_by_addr(p->val);
if (sym)
trace("$%s(0x%lX)", sym->name, sym->addr);
else
trace("0x%lX", p->val);
}
}
else if (p->type == A_IMM16)
{
if (p->val < 0xA) trace("%lu", p->val);
else trace("0x%hX", (ushort)p->val);
}
else if (p->type == A_IMM8)
{
if (p->val < 0xA) trace("%lu", p->val);
else trace("0x%hhX", (uchar)p->val);
}
else
{
trace("%c[", getmempref(p->mlen));
mfmt = p->type;
if (mfmt == AM_RR)
{
if (p->reg1 && p->reg2)
trace("%s+%s]", ctx->r[p->reg1].name, ctx->r[p->reg2].name);
else trace("%s]", ctx->r[p->reg1 ? p->reg1 : p->reg2].name);
}
else if (mfmt == AM_RRI)
{
if (p->reg1 && p->reg2)
trace("%s+%s%c%ld]",
ctx->r[p->reg1].name,
ctx->r[p->reg2].name,
(p->imm2 < 0 ? '-' : '+'),
ABS(p->imm2));
else trace("%s%c%ld]",
ctx->r[p->reg1 ? p->reg1 : p->reg2].name,
(p->imm2 < 0 ? '-' : '+'),
ABS(p->imm2));
}
else if (mfmt == AM_RRII)
{
if (p->reg1)
trace("%s+%s*%hhd%c%ld]",
ctx->r[p->reg1].name,
ctx->r[p->reg2].name, p->imm1,
(p->imm2 < 0 ? '-' : '+'),
ABS(p->imm2));
else
trace("%s*%hhd%c%ld]",
ctx->r[p->reg2].name, p->imm1,
(p->imm2 < 0 ? '-' : '+'),
ABS(p->imm2));
}
}
}