qemu-e2k/target/e2k/helper_aau.c

89 lines
2.2 KiB
C

#include "qemu/osdep.h"
#include "qemu/log.h"
#include "cpu.h"
#include "exec/exec-all.h"
#include "qemu/host-utils.h"
#include "exec/helper-proto.h"
static inline void init_prefetch_area(E2KAauAreaState *s, E2KAauPrefInstr pi,
uint32_t *inds)
{
s->last_page = 0;
s->last_page_valid = false;
if (pi.fmt != 0) {
s->pi = pi;
s->ldi = 0;
s->cdi = inds[pi.ind];
} else {
s->pi.raw = 0;
s->ldi = 0;
s->cdi = 0;
}
}
void HELPER(aau_load_program)(CPUE2KState *env)
{
unsigned int i;
E2KCtpr ctpr = env->ctprs[1];
if (ctpr.tag != CTPR_TAG_DISP || ctpr.opc != CTPR_OPC_LDISP) {
helper_raise_exception(env, EXCP_ILLEGAL_OPCODE);
}
for (i = 0; i < 32; i++) {
E2KAauPrefInstr l, r;
size_t offset = i * 16;
l.raw = cpu_ldq_le_data(env, ctpr.base + offset);
r.raw = cpu_ldq_le_data(env, ctpr.base + offset + 8);
init_prefetch_area(&env->aau.pl.area[i], l, env->aau.inds);
init_prefetch_area(&env->aau.pr.area[i], r, env->aau.inds);
if (l.ct || r.ct) {
break;
}
}
}
target_ulong HELPER(mova_ptr)(CPUE2KState *env, int chan, int area, int ind,
int size, int mmu_idx)
{
E2KAauPrefState *ps = chan < 2 ? &env->aau.pl : &env->aau.pr;
E2KAauAreaState *as = &ps->area[area];
E2KAauPrefInstr instr = as->pi;
E2KAad aad = env->aau.ds[instr.aad];
target_ulong addr = aad.base + as->cdi + instr.disp + ind;
target_ulong page = addr & TARGET_PAGE_MASK;
if (addr & (size - 1)) {
return 0;
} else if (page != as->last_page) {
void *ignore;
int flags;
flags = probe_access_flags(env, page, MMU_DATA_LOAD, mmu_idx,
true, &ignore, 0);
as->last_page = page;
as->last_page_valid = !(flags & TLB_INVALID_MASK);
}
return as->last_page_valid ? addr : 0;
}
void HELPER(aau_am)(CPUE2KState *env, int chan, int area)
{
E2KAauPrefState *ps = chan < 2 ? &env->aau.pl : &env->aau.pr;
E2KAauAreaState *as = &ps->area[area];
E2KAauPrefInstr instr = as->pi;
uint32_t incr = env->aau.incrs[instr.incr];
int size;
if (instr.fmt == 0) {
return;
}
size = 1 << (instr.fmt - 1);
as->cdi += size * incr;
}