qemu-e2k/target/e2k/cpu-dump.c

183 lines
5.6 KiB
C

/*
* e2k CPU dump to file
*
* Copyright (c) 2021 Denis Drakhnya
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include "qemu/osdep.h"
#include "cpu.h"
#include "helper-tcg.h"
#include "qemu/qemu-print.h"
static inline const char *indent(int width, int max_width)
{
static const char s[] = " ";
assert(width < sizeof(s) && max_width < sizeof(s));
return s + sizeof(s) - 1 - max_width + width;
}
static void dump_psp(FILE *f, int flags, const char *name, E2KPsp *psp,
bool newline)
{
qemu_fprintf(f, "%s %016" PRIx64 " base %016" PRIx64 " index %08" PRIx32
" size %08" PRIx32 " %c%c itag=%x%s",
name,
(uint64_t) psp->base + psp->index,
(uint64_t) psp->base,
(uint32_t) psp->index,
(uint32_t) psp->size,
psp->is_readable ? 'R' : ' ',
psp->is_writable ? 'W' : ' ',
(int) psp->itag,
newline ? "\n" : "");
}
static void dump_rwap(FILE *f, int flags, const char *name, E2KRwap *rwap,
bool newline)
{
qemu_fprintf(f, "%s %016" PRIx64 " base %016" PRIx64 " curptr %08" PRIx32
" size %08" PRIx32 " %c%c%c%s",
name,
(uint64_t) rwap->base + rwap->curptr,
(uint64_t) rwap->base,
(uint32_t) rwap->curptr,
(uint32_t) rwap->size,
rwap->protected ? 'P' : ' ',
rwap->read ? 'R' : ' ',
rwap->write ? 'W' : ' ',
newline ? "\n" : "");
}
static void dump_lsr(CPUE2KState *env, FILE *f, int flags)
{
qemu_fprintf(f,
" lcnt %016" PRIx64 " pcnt=%02x ecnt=%02x vlc=%d ldmc=%d ldovl=%02x\n"
"ilcnt %016" PRIx64 " ipcnt=%02x iecnt=%02x over=%d semc=%d strmd=%02x\n",
env->lsr_lcnt,
(int) env->lsr_pcnt,
(int) env->lsr_ecnt,
(int) env->lsr_vlc,
(int) extract32(env->lsr, LSR_LDMC_OFF - 32, 1),
(int) extract32(env->lsr, LSR_LDOVL_OFF - 32, LSR_LDOVL_LEN),
env->ilcr_lcnt,
(int) extract32(env->ilcr, LSR_PCNT_OFF - 32, LSR_PCNT_LEN),
(int) extract32(env->ilcr, LSR_ECNT_OFF - 32, LSR_ECNT_LEN),
(int) env->lsr_over,
(int) extract32(env->lsr, LSR_SEMC_OFF - 32, 1),
(int) env->lsr_strmd
);
}
static void dump_predicate_regs(CPUE2KState *env, FILE *f, int flags)
{
int i;
qemu_fprintf(f, "pred");
for (i = 0; i < 32; i++) {
qemu_fprintf(f, "%s%d", indent(i > 9, 2), i);
}
qemu_fprintf(f, "\n ");
for (i = 0; i < 32; i++) {
int index = i < env->bp.size ? (i + env->bp.cur) % env->bp.size : i;
int preg = (env->pregs >> (index * 2)) & 3;
qemu_fprintf(f, " %c%d", preg >> 1 ? '*' : ' ', preg & 1);
}
qemu_fprintf(f, "\n");
}
static inline void dump_reg(FILE *f, char mnemonic, int index,
uint8_t tag, E2KReg reg)
{
int width = (index > 9) + (index > 99);
const char *prefix = indent(width, 3 - ((index & 3) == 0));
uint8_t tag_lo = tag & 3;
uint8_t tag_hi = (tag >> 2) & 3;
qemu_fprintf(f, "%s%c%d <%d%d>%016" PRIx64, prefix, mnemonic, index,
tag_hi, tag_lo, reg.lo);
if ((index & 3) == 3) {
qemu_fprintf(f, "\n");
}
}
static void dump_regs(CPUE2KState *env, FILE *f, int flags)
{
int i;
for (i = 0; i < env->wd.size; i++) {
dump_reg(f, 'r', i, env->tags[i], env->regs[i]);
}
if (env->wd.size & 3) {
qemu_fprintf(f, "\n");
}
if ((env->wd.size - env->bn.base) >= env->bn.size) {
for (i = 0; i < env->bn.size; i++) {
int index = env->bn.base + (i + env->bn.cur) % env->bn.size;
dump_reg(f, 'b', i, env->tags[index], env->regs[index]);
}
if (env->bn.size & 3) {
qemu_fprintf(f, "\n");
}
}
for (i = 0; i < 32; i++) {
int index = E2K_NR_COUNT + i;
dump_reg(f, 'g', i, env->tags[index], env->regs[index]);
}
}
void e2k_cpu_dump_state(CPUState *cs, FILE *f, int flags)
{
E2KCPU *cpu = E2K_CPU(cs);
CPUE2KState *env = &cpu->env;
qemu_fprintf(f,
" ip %016" PRIx64 " ctpr1 %016" PRIx64 " ctpr2 %016" PRIx64 " ctpr3 %016" PRIx64 "\n"
" sbr %016" PRIx64 " osr0 %016" PRIx64 " psr=%02x upsr=%04x\n",
(uint64_t) env->ip,
env->ctprs[0].raw,
env->ctprs[1].raw,
env->ctprs[2].raw,
env->sbr,
env->osr0,
(int) env->psr,
(int) env->upsr
);
dump_rwap(f, flags, " usd", &env->usd, true);
dump_psp(f, flags, " pcsp", &env->pcsp, true);
dump_psp(f, flags, " psp", &env->psp, true);
dump_rwap(f, flags, "oscud", &env->oscud, true);
dump_rwap(f, flags, " osgd", &env->osgd, true);
dump_rwap(f, flags, " cud", &env->cud, true);
dump_rwap(f, flags, " gd", &env->gd, true);
dump_lsr(env, f, flags);
qemu_fprintf(f, " wsz=%d wbdl=%d rbs=%d rsz=%d rcur=%d psz=%d pcur=%d\n",
(int) env->wd.size,
(int) env->wdbl,
(int) env->bn.base,
(int) env->bn.size,
(int) env->bn.cur,
(int) env->bp.size,
(int) env->bp.cur
);
dump_predicate_regs(env, f, flags);
dump_regs(env, f, flags);
}