target: e2k: Impl rotated pregs.

This commit is contained in:
Denis Drakhnia 2020-11-13 16:49:28 +02:00 committed by Denis Drakhnia
parent 2f482cf83c
commit 37acf287ad
13 changed files with 139 additions and 36 deletions

View File

@ -65,4 +65,6 @@ void cpu_loop(CPUE2KState *env)
void target_cpu_copy_regs(CPUE2KState *env, struct target_pt_regs *regs)
{
env->ip = regs->ip;
env->usd_hi = regs->usd_hi;
env->usd_lo = regs->usd_lo;
}

View File

@ -77,6 +77,7 @@ struct target_sigcontext {
void setup_frame(int sig, struct target_sigaction *ka,
target_sigset_t *set, CPUE2KState *env)
{
/* TODO */
qemu_log_mask(LOG_UNIMP, "setup_frame: not implemented\n");
}
@ -84,18 +85,21 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
target_siginfo_t *info,
target_sigset_t *set, CPUE2KState *env)
{
/* TODO */
qemu_log_mask(LOG_UNIMP, "setup_rt_frame: not implemented\n");
}
long do_sigreturn(CPUE2KState *env)
{
// TODO
/* TODO */
qemu_log_mask(LOG_UNIMP, "do_sigreturn: not implemented\n");
return 0;
}
long do_rt_sigreturn(CPUE2KState *env)
{
trace_user_do_rt_sigreturn(env, 0);
/* TODO */
qemu_log_mask(LOG_UNIMP, "do_rt_sigreturn: not implemented\n");
return -TARGET_ENOSYS;
}
@ -103,7 +107,7 @@ long do_rt_sigreturn(CPUE2KState *env)
abi_long do_swapcontext(CPUArchState *env, abi_ulong uold_ctx,
abi_ulong unew_ctx, abi_long ctx_size)
{
// TODO
/* TODO */
qemu_log_mask(LOG_UNIMP, "do_swapcontext: not implemented\n");
return 0;
}

View File

@ -1,32 +1,40 @@
#ifndef E2K_TARGET_CPU_H
#define E2K_TARGET_CPU_H
#include "qemu/log.h"
static inline void cpu_clone_regs_child(CPUE2KState *env, target_ulong newsp,
unsigned flags)
{
// TODO
if (newsp) {
uint64_t size = 0x20000UL;
env->usd_hi = size << 32;
env->usd_lo = (0x1800UL << 48) | newsp;
}
}
static inline void cpu_clone_regs_parent(CPUE2KState *env, unsigned flags)
{
qemu_log_mask(LOG_UNIMP, "cpu_clone_regs_parent: unimplemented\n");
// TODO
}
static inline void cpu_set_tls(CPUE2KState *env, target_ulong newtls)
{
qemu_log_mask(LOG_UNIMP, "cpu_set_tls: unimplemented\n");
// TODO
}
static inline target_ulong cpu_get_tls(CPUE2KState *env)
{
// TODO
qemu_log_mask(LOG_UNIMP, "cpu_get_tls: unimplemented\n");
return 0;
}
static inline abi_ulong get_sp_from_cpustate(CPUE2KState *state)
static inline abi_ulong get_sp_from_cpustate(CPUE2KState *env)
{
// TODO
return 0;
return env->usd_lo & ((1UL << 48) - 1);
}
#endif /* E2K_TARGET_CPU_H */

View File

@ -1616,7 +1616,10 @@ typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG];
static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
{
uint64_t size = infop->start_stack - infop->stack_limit;
regs->ip = infop->entry;
regs->usd_hi = size << 32;
regs->usd_lo = (0x1800UL << 48) | infop->start_stack;
// TODO
qemu_log_mask(LOG_UNIMP, "init_thread: not implemented\n");
}

View File

@ -45,9 +45,6 @@ static void e2k_cpu_reset(DeviceState *dev)
memset(env, 0, offsetof(CPUE2KState, end_reset_fields));
env->win_ptr = env->wregs;
env->usd_hi = 0x2088000000000UL;
env->usd_lo = 0x1800c2dfffffe880UL;
}
#ifdef CONFIG_SOFTMMU
@ -84,8 +81,9 @@ void e2k_cpu_dump_state(CPUState *cs, FILE *f, int flags)
qemu_fprintf(f, "ip: " TARGET_FMT_lx "\n", env->ip);
qemu_fprintf(f, "pregs: %016lx\n", env->pregs);
qemu_fprintf(f, "%%usd.hi: %016lx\n", env->usd_hi);
qemu_fprintf(f, "%%usd.lo: %016lx\n", env->usd_lo);
qemu_fprintf(f, "usd_hi: %016lx, usd_lo: %016lx\n",
env->usd_hi, env->usd_lo);
qemu_fprintf(f, "psz: %d, pcur: %d\n", (int) env->psz, (int) env->pcur);
for (i = 0; i < 192; i += 4) {
const char *s1 = i < 10 ? " " : (i < 100 ? " " : "");

View File

@ -30,14 +30,19 @@ typedef struct CPUArchState {
target_ulong wregs[WREGS_SIZE]; // window regs
target_ulong *win_ptr;
uint64_t pregs;
uint32_t wbs; // Real window regs offset, in bundle it comes divided by 2
uint32_t wsz; // Real window regs size, in bundle it comes divided by 2
uint32_t nfx; // TODO
uint32_t dbl; // TODO
/* TODO: move them to %br? */
uint32_t rbs; // Real based regs offset, in bundle it comes divided by 2
uint32_t rsz; // Real based regs size, in bundle it comes divided by 2 minus 2
uint32_t rcur; // Real based regs current index, in bundle it comes divided by 2
uint32_t psz; // pred regs window size
uint32_t rcur; // Real based regs current offset, in bundle it comes divided by 2
uint64_t psz; // pred regs window size
uint64_t pcur; // pred regs current offset
uint32_t syscall_wbs;
uint64_t usd_lo;

View File

@ -1,4 +1,5 @@
#include "qemu/osdep.h"
#include "qemu/log.h"
#include "cpu.h"
#include "exec/exec-all.h"
#include "qemu/host-utils.h"
@ -52,3 +53,13 @@ uint64_t helper_sxt(uint64_t x, uint64_t y)
return (((int64_t) y) << (64 - size) >> (64 - size));
}
}
void helper_debug_i32(uint32_t x)
{
qemu_log_mask(LOG_UNIMP, "log %#x\n", x);
}
void helper_debug_i64(uint64_t x)
{
qemu_log_mask(LOG_UNIMP, "log %#lx\n", x);
}

View File

@ -1,3 +1,5 @@
DEF_HELPER_2(raise_exception, noreturn, env, int)
DEF_HELPER_3(call, void, env, i64, i64)
DEF_HELPER_2(sxt, i64, i64, i64)
DEF_HELPER_1(debug_i32, void, i32)
DEF_HELPER_1(debug_i64, void, i64)

View File

@ -428,12 +428,13 @@ void e2k_tcg_initialize(void) {
{ &e2k_cs.rbs, offsetof(CPUE2KState, rbs), "rbs" },
{ &e2k_cs.rsz, offsetof(CPUE2KState, rsz), "rsz" },
{ &e2k_cs.rcur, offsetof(CPUE2KState, rcur), "rcur" },
{ &e2k_cs.psz, offsetof(CPUE2KState, psz), "psz" },
{ &e2k_cs.syscall_wbs, offsetof(CPUE2KState, syscall_wbs), "syscall_wbs" },
};
static const struct { TCGv_i64 *ptr; int off; const char *name; } r64[] = {
{ &e2k_cs.pregs, offsetof(CPUE2KState, pregs), "pregs" },
{ &e2k_cs.psz, offsetof(CPUE2KState, psz), "psz" },
{ &e2k_cs.pcur, offsetof(CPUE2KState, pcur), "pcur" },
{ &e2k_cs.usd_lo, offsetof(CPUE2KState, usd_lo), "%usd.lo" },
{ &e2k_cs.usd_hi, offsetof(CPUE2KState, usd_hi), "%usd.hi" },
};

View File

@ -68,7 +68,8 @@ typedef struct CPUE2KStateTCG {
TCGv_i32 rbs;
TCGv_i32 rsz;
TCGv_i32 rcur;
TCGv_i32 psz;
TCGv_i64 psz;
TCGv_i64 pcur;
TCGv_i32 syscall_wbs;
TCGv_ptr win_ptr;
TCGv_i64 wregs[WREGS_SIZE];
@ -177,6 +178,17 @@ static inline void e2k_gen_wrap_i32(TCGv_i32 ret, TCGv_i32 x, TCGv_i32 y)
tcg_temp_free_i32(t0);
}
// FIXME: x must not be greater than y * 2
static inline void e2k_gen_wrap_i64(TCGv_i64 ret, TCGv_i64 x, TCGv_i64 y)
{
TCGv_i64 t0 = tcg_temp_new_i64();
tcg_gen_sub_i64(t0, x, y);
tcg_gen_movcond_i64(TCG_COND_LTU, ret, x, y, x, t0);
tcg_temp_free_i64(t0);
}
static inline void e2k_gen_get_field_i64(TCGv_i64 ret, TCGv_i64 val,
unsigned int start, unsigned int end)
{
@ -204,7 +216,7 @@ static inline void e2k_gen_set_field_i64(TCGv_i64 ret, TCGv_i64 val,
tcg_temp_free_i64(t0);
}
TCGv_i64 e2k_gen_preg(TCGv_i64 ret, int reg);
void e2k_gen_preg(TCGv_i64 ret, int reg);
TCGv_i64 e2k_get_preg(DisasContext *dc, int reg);
void e2k_gen_store_preg(int reg, TCGv_i64 val);
TCGv_i64 e2k_get_wreg(DisasContext *dc, int reg);

View File

@ -211,9 +211,7 @@ static void gen_cs1(DisasContext *dc)
}
if (setbp) {
unsigned int psz = (cs1 & 0x007c0000) >> 18;
tcg_gen_movi_i32(e2k_cs.psz, psz);
tcg_gen_movi_i64(e2k_cs.psz, GET_FIELD(cs1, 18, 23));
}
} else if (opc == SETEI) {
/* Verify that CS1.param.sft = CS1.param[27] is equal to zero as required

View File

@ -3,6 +3,52 @@
#include "exec/log.h"
#include "translate.h"
static void gen_preg_offset(TCGv_i64 ret, int reg)
{
assert(reg < 32);
TCGv_i64 t0 = tcg_temp_new_i64();
TCGv_i64 t1 = tcg_temp_new_i64();
TCGv_i64 t2 = tcg_temp_new_i64();
tcg_gen_addi_i64(t0, e2k_cs.pcur, reg);
tcg_gen_addi_i64(t1, e2k_cs.psz, 1);
e2k_gen_wrap_i64(t2, t0, t1);
tcg_gen_shli_i64(ret, t2, 1);
tcg_temp_free_i64(t2);
tcg_temp_free_i64(t1);
tcg_temp_free_i64(t0);
}
static void gen_preg_clear(TCGv_i64 ret, TCGv_i64 offset)
{
TCGv_i64 t0 = tcg_const_i64(3);
TCGv_i64 t1 = tcg_temp_new_i64();
TCGv_i64 t2 = tcg_temp_new_i64();
tcg_gen_shr_i64(t1, t0, offset);
tcg_gen_not_i64(t2, t1);
tcg_gen_and_i64(ret, t2, e2k_cs.pregs);
tcg_temp_free_i64(t2);
tcg_temp_free_i64(t1);
tcg_temp_free_i64(t0);
}
void e2k_gen_preg(TCGv_i64 ret, int reg)
{
TCGv_i64 t0 = tcg_temp_new_i64();
TCGv_i64 t1 = tcg_temp_new_i64();
gen_preg_offset(t0, reg);
tcg_gen_shri_i64(t1, e2k_cs.pregs, reg * 2);
tcg_gen_andi_i64(ret, t1, 0x01);
tcg_temp_free_i64(t1);
tcg_temp_free_i64(t0);
}
TCGv_i64 e2k_get_preg(DisasContext *dc, int reg)
{
TCGv_i64 ret = e2k_get_temp_i64(dc);
@ -10,26 +56,19 @@ TCGv_i64 e2k_get_preg(DisasContext *dc, int reg)
return ret;
}
TCGv_i64 e2k_gen_preg(TCGv_i64 ret, int reg)
{
TCGv_i64 tmp = tcg_temp_new_i64();
assert(reg < 32);
tcg_gen_shri_i64(tmp, e2k_cs.pregs, reg * 2);
// TODO: should return preg tag?
tcg_gen_andi_i64(ret, tmp, 0x01);
tcg_temp_free_i64(tmp);
return ret;
}
void e2k_gen_store_preg(int reg, TCGv_i64 val)
{
TCGv_i64 t0 = tcg_temp_new_i64();
TCGv_i64 t1 = tcg_temp_new_i64();
TCGv_i64 t2 = tcg_temp_new_i64();
tcg_gen_andi_i64(t0, e2k_cs.pregs, ~(3 << (reg * 2)));
tcg_gen_andi_i64(t1, val, 0x03);
tcg_gen_shli_i64(t2, t1, reg * 2);
tcg_gen_or_i64(e2k_cs.pregs, t0, t2);
TCGv_i64 t2 = tcg_const_i64(1);
TCGv_i64 t3 = tcg_temp_new_i64();
gen_preg_offset(t0, reg);
gen_preg_clear(t1, t0);
tcg_gen_shl_i64(t3, t2, t0);
tcg_gen_or_i64(e2k_cs.pregs, t1, t3);
tcg_temp_free_i64(t3);
tcg_temp_free_i64(t2);
tcg_temp_free_i64(t1);
tcg_temp_free_i64(t0);

View File

@ -3,6 +3,21 @@
#include "exec/log.h"
#include "translate.h"
static inline void gen_abp_inc(DisasContext *dc, TCGCond cond)
{
TCGv_i64 t0 = tcg_temp_new_i64();
TCGv_i64 t1 = tcg_temp_new_i64();
TCGv_i64 one = tcg_const_i64(1);
tcg_gen_subi_i64(t0, e2k_cs.pcur, 1);
tcg_gen_umin_i64(t1, t0, e2k_cs.psz);
tcg_gen_movcond_i64(cond, e2k_cs.pcur, dc->jmp.cond, one, t1, e2k_cs.pcur);
tcg_temp_free_i64(one);
tcg_temp_free_i64(t1);
tcg_temp_free_i64(t0);
}
static inline void gen_abn_inc(DisasContext *dc, TCGCond cond)
{
TCGv_i32 t0 = tcg_temp_new_i32();
@ -29,7 +44,6 @@ void e2k_win_commit(DisasContext *dc)
uint32_t ss = dc->bundle.ss;
// unsigned int vfdi = (ss & 0x04000000) >> 26;
// unsigned int abg = (ss & 0x01800000) >> 23;
// unsigned int abp = (ss & 0x000c0000) >> 18;
// unsigned int alc = (ss & 0x00030000) >> 16;
if (GET_BIT(ss, 21)) {
@ -38,4 +52,10 @@ void e2k_win_commit(DisasContext *dc)
if (GET_BIT(ss, 22)) {
gen_abn_inc(dc, TCG_COND_NE);
}
if (GET_BIT(ss, 18)) {
gen_abp_inc(dc, TCG_COND_EQ);
}
if (GET_BIT(ss, 19)) {
gen_abp_inc(dc, TCG_COND_NE);
}
}