kvisc/vm/pc/dump.c

213 lines
4.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>
char *cond_suffixes[] =
{
"-",
"c", "o", "z", "s", "p",
"a", "ae", "b", "be",
"g", "ge", "l", "le",
"cxz",
"?"
};
// Comment the following line to get back intel syntax
#define _ATT_STYLE 1
static void dump_acc(ctx_t *ctx, acc_t *p);
void dump_instr(ctx_t *ctx,
instr_t *in,
acc_t *p1,
acc_t *p2,
bool lock,
bool rep,
uint cond,
ulong pc)
{
log("0x%lX:\t", pc);
if (lock)
log("lock");
#ifndef _ATT_STYLE
log("%s", in->name);
#else
char s1[2] = {0, 0}, s2[2] = {0, 0};
if (p1 && ACC_IS_MEM(p1))
s1[0] = getmempref(p1->mlen);
if (p2 && ACC_IS_MEM(p2))
s2[0] = getmempref(p2->mlen);
log("%s%s%s", in->name, s1, s2);
#endif
if (rep)
log(".rep");
if (cond)
{
log(".");
if (cond & (1 << 4))
{
cond &= ~(1 << 4);
log("n");
}
assert(cond <= sizeof(cond_suffixes)/sizeof(char *));
log("%s", cond_suffixes[cond]);
}
if (!rep)
log("\t\t");
else
log("\t");
if (p1) {
#ifndef _ATT_STYLE
dump_acc(ctx, p1);
if (p2) {
log(", ");
dump_acc(ctx, p2);
}
}
#else
if (p2) {
dump_acc(ctx, p2);
log(", ");
}
dump_acc(ctx, p1);
#endif
}
log("\n");
}
#ifndef _ATT_STYLE
void dump_acc(ctx_t *ctx, acc_t *p)
{
uint mfmt;
if (p->type == A_REG)
log("%s", ctx->r[p->reg].name);
else if (p->type == A_IMM64)
{
if (p->val < 0xA)
log("%lu", p->val);
else
log("0x%lX", p->val);
}
else
{
log("%c[", getmempref(p->mlen));
mfmt = p->type & AM_MFMT_MASK;
if (mfmt == AM_IMM64)
log("0x%lX]", p->addr);
else if (mfmt == AM_RR)
{
if (p->reg1 && p->reg2)
log("%s+%s]", ctx->r[p->reg1].name, ctx->r[p->reg2].name);
else log("%s]", ctx->r[p->reg1 ? p->reg1 : p->reg2].name);
}
else if (mfmt == AM_RRI)
{
if (p->reg1 && p->reg2)
log("%s+%s+%hd]", ctx->r[p->reg1].name,
ctx->r[p->reg2].name, p->imm2);
else log("%s+%hd]",
ctx->r[p->reg1 ? p->reg1 : p->reg2].name, p->imm2);
}
else if (mfmt == AM_RRII)
{
if (p->reg1)
log("%s+%s*%u+%hd]",
ctx->r[p->reg1].name,
ctx->r[p->reg2].name,
p->imm1, p->imm2);
else
log("%s*%u+%hd]",
ctx->r[p->reg2].name,
p->imm1, p->imm2);
}
}
}
#else
void dump_acc(ctx_t *ctx, acc_t *p)
{
uint mfmt;
if (p->type == A_REG)
log("%%%s", ctx->r[p->reg].name);
else if (p->type == A_IMM64)
{
if (p->val < 0xA)
log("$%lu", p->val);
else
log("$0x%lX", p->val);
}
else
{
mfmt = p->type & AM_MFMT_MASK;
if (mfmt == AM_IMM64)
log("($0x%lX)", p->addr);
else if (mfmt == AM_RR)
{
if (p->reg1 && p->reg2)
log("(%%%s,%%%s)", ctx->r[p->reg1].name, ctx->r[p->reg2].name);
else log("(%%%s)", ctx->r[p->reg1 ? p->reg1 : p->reg2].name);
}
else if (mfmt == AM_RRI)
{
if (p->reg1 && p->reg2)
log("%hd(%%%s,%%%s)", p->imm2, ctx->r[p->reg1].name,
ctx->r[p->reg2].name);
else log("%hd(%%%s)", p->imm2,
ctx->r[p->reg1 ? p->reg1 : p->reg2].name);
}
else if (mfmt == AM_RRII)
{
if (p->reg1)
log("%hd(%s,%s,$%u)", p->imm2,
ctx->r[p->reg1].name,
ctx->r[p->reg2].name,
p->imm1);
else
log("%hd(*,%s,$%u)", p->imm2,
ctx->r[p->reg2].name,
p->imm1);
}
}
}
#endif