From ba89b350dc299b988d4d1bd344f22611fff99212 Mon Sep 17 00:00:00 2001 From: Denis Drakhnya Date: Mon, 22 Mar 2021 20:07:29 +0200 Subject: [PATCH] e2k: signals: Save and restore more state. Signed-off-by: Denis Drakhnya --- linux-user/e2k/signal.c | 53 +++++++++++++--------- target/e2k/cpu.c | 11 ++--- target/e2k/cpu.h | 75 ------------------------------- target/e2k/gdbstub.c | 11 ++--- target/e2k/helper-tcg.h | 98 +++++++++++++++++++++++++++++++++++++++++ target/e2k/helper.c | 16 +------ target/e2k/helper.h | 1 - target/e2k/helper_int.c | 31 ++++--------- target/e2k/translate.c | 7 +-- 9 files changed, 153 insertions(+), 150 deletions(-) diff --git a/linux-user/e2k/signal.c b/linux-user/e2k/signal.c index 81cac82971..511b389d05 100644 --- a/linux-user/e2k/signal.c +++ b/linux-user/e2k/signal.c @@ -23,6 +23,7 @@ #include "user-internals.h" #include "signal-common.h" #include "linux-user/trace.h" +#include "target/e2k/helper-tcg.h" #define MAX_TC_SIZE 10 @@ -106,17 +107,18 @@ struct target_sigframe { struct target_ucontext uc; // TODO: ucontext_prot }; - target_sigset_t saved_set; - // FIXME: find where AAU state is saved + /* FIXME: move this data to TaskState? */ E2KAauState aau; + uint64_t lsr; + uint64_t lsr_lcnt; + // FIXME: according to ABI only 16-31 must be saved + E2KReg gregs[16]; + uint8_t gtags[16]; }; #define NF_ALIGNEDSZ (((sizeof(struct target_signal_frame) + 7) & (~7))) -void helper_signal_frame(CPUE2KState *env, int wbs, target_ulong ret_ip); -void helper_signal_return(CPUE2KState *env); - static abi_long setup_sigcontext(CPUE2KState *env, struct target_sigcontext *sc, struct target_extra_ucontext *extra) { @@ -203,7 +205,7 @@ static void target_setup_frame(int sig, struct target_sigaction *ka, } /* save current frame */ - helper_signal_frame(env, env->wd.size, env->ip); + e2k_proc_call(env, env->wd.size, env->ip, false); frame_addr = get_sigframe(ka, env, sizeof(*frame)); trace_user_setup_rt_frame(env, frame_addr); @@ -213,8 +215,16 @@ static void target_setup_frame(int sig, struct target_sigaction *ka, if (setup_ucontext(&frame->uc, env)) { goto fail; } - copy_to_user((uintptr_t) &frame->uc.uc_sigmask, set, sizeof(*set)); - copy_to_user((uintptr_t) &frame->aau, &env->aau, sizeof(env->aau)); + copy_to_user(frame_addr + offsetof(struct target_sigframe, uc.uc_sigmask), + set, sizeof(*set)); + copy_to_user(frame_addr + offsetof(struct target_sigframe, aau), + &env->aau, sizeof(env->aau)); + __put_user(env_lsr_get(env), &frame->lsr); + __put_user(env->lsr_lcnt, &frame->lsr_lcnt); + copy_to_user(frame_addr + offsetof(struct target_sigframe, gregs), + &env->regs[E2K_NR_COUNT + 16], 16 * sizeof(E2KReg)); + copy_to_user(frame_addr + offsetof(struct target_sigframe, gtags), + &env->tags[E2K_NR_COUNT + 16], 16); if (ka->sa_flags & TARGET_SA_RESTORER) { // TODO: sa_restorer? @@ -224,13 +234,11 @@ static void target_setup_frame(int sig, struct target_sigaction *ka, } /* fake kernel frame */ - env->regs[0].lo = frame_addr; - env->tags[0] = E2K_TAG_NUMBER64; - env->wd.size = 2; + env->wd.size = 0; env->wd.psize = 0; env->usd.size = env->sbr - frame_addr; env->usd.base = frame_addr; - helper_signal_frame(env, 2, E2K_SIGRET_ADDR); + e2k_proc_call(env, 0, E2K_SIGRET_ADDR, false); env->ip = ka->_sa_handler; env->regs[0].lo = sig; @@ -245,10 +253,6 @@ static void target_setup_frame(int sig, struct target_sigaction *ka, env->tags[2] = E2K_TAG_NUMBER64; } - if (env->is_bp) { - e2k_proc_call(env, env->wd.size, env->ip, true); - } - unlock_user_struct(frame, frame_addr, 1); return; @@ -274,8 +278,6 @@ static abi_long target_restore_sigframe(CPUE2KState *env, __get_user(env->ctprs[1].raw, &frame->uc.uc_extra.ctpr2); __get_user(env->ctprs[2].raw, &frame->uc.uc_extra.ctpr3); - copy_from_user(&env->aau, (uintptr_t) &frame->aau, sizeof(env->aau)); - return 0; } @@ -303,8 +305,8 @@ long do_rt_sigreturn(CPUE2KState *env) sigset_t set; /* restore fake kernel frame */ - helper_signal_return(env); - frame_addr = env->regs[0].lo; + e2k_proc_return(env, false); + frame_addr = env->usd.base; trace_user_do_rt_sigreturn(env, frame_addr); if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) { @@ -317,6 +319,14 @@ long do_rt_sigreturn(CPUE2KState *env) if (target_restore_sigframe(env, frame)) { goto badframe; } + copy_from_user(&env->aau, frame_addr + + offsetof(struct target_sigframe, aau), sizeof(env->aau)); + __get_user(env->lsr, &frame->lsr); + __get_user(env->lsr_lcnt, &frame->lsr_lcnt); + copy_from_user(&env->regs[E2K_NR_COUNT + 16], frame_addr + + offsetof(struct target_sigframe, gregs), 16 * sizeof(E2KReg)); + copy_from_user(&env->tags[E2K_NR_COUNT + 16], frame_addr + + offsetof(struct target_sigframe, gtags), 16); if (do_sigaltstack(frame_addr + offsetof(struct target_sigframe, uc.uc_stack), @@ -325,7 +335,8 @@ long do_rt_sigreturn(CPUE2KState *env) goto badframe; } - env->ip = E2K_SIGRET_ADDR; + /* restore user */ + e2k_proc_return(env, false); unlock_user_struct(frame, frame_addr, 0); return -QEMU_ESIGRETURN; diff --git a/target/e2k/cpu.c b/target/e2k/cpu.c index 8ef2e86aed..b283b5e84e 100644 --- a/target/e2k/cpu.c +++ b/target/e2k/cpu.c @@ -21,6 +21,7 @@ #include "qemu/log.h" #include "qapi/error.h" #include "cpu.h" +#include "helper-tcg.h" #include "qemu/module.h" #include "qemu/qemu-print.h" #include "exec/exec-all.h" @@ -136,7 +137,7 @@ static const struct e2k_def_t e2k_defs[] = { static inline void cpu_dump_state_br(CPUE2KState *env, FILE *f, int flags) { - uint32_t br = e2k_state_br(env); + uint32_t br = env_br_get(env); E2KBnState *bn = &env->bn; E2KBpState *bp = &env->bp; @@ -156,10 +157,10 @@ 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 = 0x%016lx\n", env->pregs); - qemu_fprintf(f, " pcsp_lo = 0x%016lx\n", e2k_state_pcsp_lo(env)); - qemu_fprintf(f, " pcsp_hi = 0x%016lx\n", e2k_state_pcsp_hi(env)); - qemu_fprintf(f, " psp_lo = 0x%016lx\n", e2k_state_psp_lo(env)); - qemu_fprintf(f, " psp_hi = 0x%016lx\n", e2k_state_psp_hi(env)); + qemu_fprintf(f, " pcsp_lo = 0x%016lx\n", env_pcsp_lo_get(env)); + qemu_fprintf(f, " pcsp_hi = 0x%016lx\n", env_pcsp_hi_get(env)); + qemu_fprintf(f, " psp_lo = 0x%016lx\n", env_psp_lo_get(env)); + qemu_fprintf(f, " psp_hi = 0x%016lx\n", env_psp_hi_get(env)); qemu_fprintf(f, " usd_lo = 0x%016lx\n", env->usd.lo); qemu_fprintf(f, " usd_hi = 0x%016lx\n", env->usd.hi); qemu_fprintf(f, " lsr = 0x%016lx\n", env->lsr); diff --git a/target/e2k/cpu.h b/target/e2k/cpu.h index e603e76b7a..67c393f49c 100644 --- a/target/e2k/cpu.h +++ b/target/e2k/cpu.h @@ -841,81 +841,6 @@ void e2k_proc_return(CPUE2KState *env, bool force_fx); #define cpu_signal_handler e2k_cpu_signal_handler #define cpu_list e2k_cpu_list -static inline uint64_t e2k_state_desc_lo(E2KStackState *desc) -{ - uint64_t lo = 0; - - lo = deposit64(lo, DESC_LO_BASE_OFF, DESC_LO_BASE_LEN, - (uint64_t) desc->base); - lo = deposit64(lo, DESC_LO_READ_OFF, 1, desc->is_readable); - lo = deposit64(lo, DESC_LO_WRITE_OFF, 1, desc->is_writable); - - return lo; -} - -static inline uint64_t e2k_state_desc_hi(E2KStackState *env) -{ - uint64_t hi = 0; - - hi = deposit64(hi, DESC_HI_IND_OFF, DESC_HI_IND_LEN, env->index); - hi = deposit64(hi, DESC_HI_SIZE_OFF, DESC_HI_SIZE_OFF, env->size); - - return hi; -} - -#define e2k_state_pcsp_lo(env) e2k_state_desc_lo(&(env)->pcsp) -#define e2k_state_pcsp_hi(env) e2k_state_desc_hi(&(env)->pcsp) -#define e2k_state_psp_lo(env) e2k_state_desc_lo(&(env)->psp) -#define e2k_state_psp_hi(env) e2k_state_desc_hi(&(env)->psp) - -static inline uint64_t e2k_state_wd(CPUE2KState *env) -{ - E2KWdState *wd = &env->wd; - uint64_t ret = 0; - - ret = deposit64(ret, WD_SIZE_OFF, WD_SIZE_LEN, wd->size * 8); - ret = deposit64(ret, WD_PSIZE_OFF, WD_PSIZE_LEN, wd->psize * 8); - ret = deposit64(ret, WD_FX_OFF, 1, wd->fx); - - return ret; -} - -static inline void e2k_state_wd_set(CPUE2KState *env, uint64_t raw) -{ - env->wd.size = extract64(raw, WD_SIZE_OFF, WD_SIZE_LEN) / 8; - env->wd.psize = extract64(raw, WD_PSIZE_OFF, WD_PSIZE_LEN) / 8; - env->wd.fx = extract64(raw, WD_FX_OFF, 1); -} - -static inline uint32_t e2k_state_br(CPUE2KState *env) -{ - E2KBnState *bn = &env->bn; - E2KBpState *bp = &env->bp; - uint32_t ret = 0; - - ret = deposit32(ret, BR_RBS_OFF, BR_RBS_LEN, bn->base / 2); - ret = deposit32(ret, BR_RSZ_OFF, BR_RSZ_LEN, bn->size / 2 - 1); - ret = deposit32(ret, BR_RCUR_OFF, BR_RCUR_LEN, bn->cur / 2); - - ret = deposit32(ret, BR_PSZ_OFF, BR_PSZ_LEN, bp->size - 1); - ret = deposit32(ret, BR_PCUR_OFF, BR_PCUR_LEN, bp->cur); - - return ret; -} - -static inline void e2k_state_br_set(CPUE2KState *env, uint32_t br) -{ - E2KBnState *bn = &env->bn; - E2KBpState *bp = &env->bp; - - bn->base = extract32(br, BR_RBS_OFF, BR_RBS_LEN) * 2; - bn->size = extract32(br, BR_RSZ_OFF, BR_RSZ_LEN) * 2 + 2; - bn->cur = extract32(br, BR_RCUR_OFF, BR_RCUR_LEN) * 2; - - bp->size = extract32(br, BR_PSZ_OFF, BR_PSZ_LEN) + 1; - bp->cur = extract32(br, BR_PCUR_OFF, BR_PCUR_LEN); -} - #include "exec/cpu-all.h" #endif diff --git a/target/e2k/gdbstub.c b/target/e2k/gdbstub.c index 6b4b487db7..cc45c6cd93 100644 --- a/target/e2k/gdbstub.c +++ b/target/e2k/gdbstub.c @@ -21,6 +21,7 @@ #include "qemu/osdep.h" #include "qemu/timer.h" #include "cpu.h" +#include "helper-tcg.h" #include "exec/gdbstub.h" /* TODO: reverse engineer e2k-linux-gdb register ids */ @@ -65,8 +66,8 @@ int e2k_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) case 46: return gdb_get_reg64(mem_buf, 0); // usbr case 47: return gdb_get_reg64(mem_buf, env->usd.lo); // usd_lo case 48: return gdb_get_reg64(mem_buf, env->usd.hi); // usd_hi - case 49: return gdb_get_reg64(mem_buf, e2k_state_psp_lo(env)); // psp_lo - case 50: return gdb_get_reg64(mem_buf, e2k_state_psp_hi(env)); // psp_hi + case 49: return gdb_get_reg64(mem_buf, env_psp_lo_get(env)); // psp_lo + case 50: return gdb_get_reg64(mem_buf, env_psp_hi_get(env)); // psp_hi case 51: return gdb_get_reg64(mem_buf, 0); // pshtp case 52: return gdb_get_reg64(mem_buf, env->pregs); // pregs case 53: return gdb_get_reg64(mem_buf, env->ip); // ip @@ -79,8 +80,8 @@ int e2k_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) return gdb_get_reg64(mem_buf, cr1_hi); } case 56: return gdb_get_reg64(mem_buf, 0); // cwd - case 57: return gdb_get_reg64(mem_buf, e2k_state_pcsp_lo(env)); // pcsp_lo - case 58: return gdb_get_reg64(mem_buf, e2k_state_pcsp_hi(env)); // pcsp_hi + case 57: return gdb_get_reg64(mem_buf, env_pcsp_lo_get(env)); // pcsp_lo + case 58: return gdb_get_reg64(mem_buf, env_pcsp_hi_get(env)); // pcsp_hi case 59: return gdb_get_reg64(mem_buf, 0); // pcshtp case 60: return gdb_get_reg64(mem_buf, 0); // cud_lo case 61: return gdb_get_reg64(mem_buf, 0); // cud_hi @@ -175,7 +176,7 @@ int e2k_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) case 331: return gdb_get_reg64(mem_buf, 0); // dtcr case 332: return gdb_get_reg64(mem_buf, 0); // dtarf case 333: return gdb_get_reg64(mem_buf, 0); // dtart - case 334: return gdb_get_reg64(mem_buf, e2k_state_wd(env)); // wd + case 334: return gdb_get_reg64(mem_buf, env_wd_get(env)); // wd case 335: return gdb_get_reg64(mem_buf, 0); // unk case 336: return gdb_get_reg64(mem_buf, 0); // bgr case 337: return gdb_get_reg64(mem_buf, 0); // unk diff --git a/target/e2k/helper-tcg.h b/target/e2k/helper-tcg.h index 09ead4b265..424a6587c4 100644 --- a/target/e2k/helper-tcg.h +++ b/target/e2k/helper-tcg.h @@ -39,4 +39,102 @@ void G_NORETURN raise_exception(CPUE2KState *env, int exception_index); void G_NORETURN raise_exception_ra(CPUE2KState *env, int exception_index, uintptr_t retaddr); +static inline uint64_t stack_desc_lo(E2KStackState *desc) +{ + uint64_t lo = 0; + + lo = deposit64(lo, DESC_LO_BASE_OFF, DESC_LO_BASE_LEN, + (uint64_t) desc->base); + lo = deposit64(lo, DESC_LO_READ_OFF, 1, desc->is_readable); + lo = deposit64(lo, DESC_LO_WRITE_OFF, 1, desc->is_writable); + + return lo; +} + +static inline uint64_t stack_desc_hi(E2KStackState *env) +{ + uint64_t hi = 0; + + hi = deposit64(hi, DESC_HI_IND_OFF, DESC_HI_IND_LEN, env->index); + hi = deposit64(hi, DESC_HI_SIZE_OFF, DESC_HI_SIZE_OFF, env->size); + + return hi; +} + +#define env_pcsp_lo_get(env) stack_desc_lo(&(env)->pcsp) +#define env_pcsp_hi_get(env) stack_desc_hi(&(env)->pcsp) +#define env_psp_lo_get(env) stack_desc_lo(&(env)->psp) +#define env_psp_hi_get(env) stack_desc_hi(&(env)->psp) + +static inline uint64_t env_wd_get(CPUE2KState *env) +{ + E2KWdState *wd = &env->wd; + uint64_t ret = 0; + + ret = deposit64(ret, WD_SIZE_OFF, WD_SIZE_LEN, wd->size * 8); + ret = deposit64(ret, WD_PSIZE_OFF, WD_PSIZE_LEN, wd->psize * 8); + ret = deposit64(ret, WD_FX_OFF, 1, wd->fx); + + return ret; +} + +static inline void env_wd_set(CPUE2KState *env, uint64_t raw) +{ + env->wd.size = extract64(raw, WD_SIZE_OFF, WD_SIZE_LEN) / 8; + env->wd.psize = extract64(raw, WD_PSIZE_OFF, WD_PSIZE_LEN) / 8; + env->wd.fx = extract64(raw, WD_FX_OFF, 1); +} + +static inline uint32_t env_br_get(CPUE2KState *env) +{ + E2KBnState *bn = &env->bn; + E2KBpState *bp = &env->bp; + uint32_t ret = 0; + + ret = deposit32(ret, BR_RBS_OFF, BR_RBS_LEN, bn->base / 2); + ret = deposit32(ret, BR_RSZ_OFF, BR_RSZ_LEN, bn->size / 2 - 1); + ret = deposit32(ret, BR_RCUR_OFF, BR_RCUR_LEN, bn->cur / 2); + + ret = deposit32(ret, BR_PSZ_OFF, BR_PSZ_LEN, bp->size - 1); + ret = deposit32(ret, BR_PCUR_OFF, BR_PCUR_LEN, bp->cur); + + return ret; +} + +static inline void env_br_set(CPUE2KState *env, uint32_t br) +{ + E2KBnState *bn = &env->bn; + E2KBpState *bp = &env->bp; + + bn->base = extract32(br, BR_RBS_OFF, BR_RBS_LEN) * 2; + bn->size = extract32(br, BR_RSZ_OFF, BR_RSZ_LEN) * 2 + 2; + bn->cur = extract32(br, BR_RCUR_OFF, BR_RCUR_LEN) * 2; + + bp->size = extract32(br, BR_PSZ_OFF, BR_PSZ_LEN) + 1; + bp->cur = extract32(br, BR_PCUR_OFF, BR_PCUR_LEN); +} + +static inline uint64_t env_lsr_get(CPUE2KState *env) +{ + uint64_t lsr = env->lsr; + lsr = deposit64(lsr, LSR_LCNT_OFF, LSR_LCNT_LEN, env->lsr_lcnt); + lsr = deposit64(lsr, LSR_ECNT_OFF, LSR_ECNT_LEN, env->lsr_ecnt); + lsr = deposit64(lsr, LSR_VLC_OFF, 1, env->lsr_vlc); + lsr = deposit64(lsr, LSR_OVER_OFF, 1, env->lsr_over); + lsr = deposit64(lsr, LSR_PCNT_OFF, LSR_PCNT_LEN, env->lsr_pcnt); + lsr = deposit64(lsr, LSR_STRMD_OFF, LSR_STRMD_LEN, env->lsr_strmd); + return lsr; +} + +static inline void env_lsr_set(CPUE2KState *env, uint64_t val) +{ + env->lsr = val; + env->lsr_lcnt = extract64(val, LSR_LCNT_OFF, LSR_LCNT_LEN); + env->lsr_ecnt = extract64(val, LSR_ECNT_OFF, LSR_ECNT_LEN); + env->lsr_vlc = extract64(val, LSR_VLC_OFF, 1); + env->lsr_over = extract64(val, LSR_OVER_OFF, 1); + env->lsr_pcnt = extract64(val, LSR_PCNT_OFF, LSR_PCNT_LEN); + env->lsr_strmd = extract64(val, LSR_STRMD_OFF, LSR_STRMD_LEN); +} + #endif /* E2K_HELPER_TCG_H */ diff --git a/target/e2k/helper.c b/target/e2k/helper.c index 87d69c6053..f4d63b0d28 100644 --- a/target/e2k/helper.c +++ b/target/e2k/helper.c @@ -3,8 +3,6 @@ #include "qemu/host-utils.h" #include "exec/helper-proto.h" -void helper_signal_frame(CPUE2KState *env, int wbs, target_ulong ret_ip); - static inline void reset_ctprs(CPUE2KState *env) { unsigned int i; @@ -166,7 +164,7 @@ void e2k_proc_call(CPUE2KState *env, int base, target_ulong ret_ip, crs.cr1.wpsz = env->wd.psize / 2; crs.cr1.wfx = env->wd.fx; crs.cr1.wdbl = env->wdbl; - crs.cr1.br = e2k_state_br(env); + crs.cr1.br = env_br_get(env); crs.cr1.ussz = env->usd.size >> 4; pcs_push(env, &crs); @@ -189,7 +187,7 @@ void e2k_proc_return(CPUE2KState *env, bool force_fx) env->pregs = crs.cr0_lo; env->ip = crs.cr0_hi & ~7; - e2k_state_br_set(env, crs.cr1.br); + env_br_set(env, crs.cr1.br); env->wd.size = env->wd.psize + base; env->wd.psize = crs.cr1.wpsz * 2; env->wd.fx = crs.cr1.wfx; @@ -198,16 +196,6 @@ void e2k_proc_return(CPUE2KState *env, bool force_fx) env->usd.base = env->sbr - env->usd.size; } -void HELPER(signal_frame)(CPUE2KState *env, int wd_size, target_ulong ret_ip) -{ - e2k_proc_call(env, wd_size, ret_ip, false); -} - -void HELPER(signal_return)(CPUE2KState *env) -{ - e2k_proc_return(env, false); -} - static inline void do_call(CPUE2KState *env, int wbs, target_ulong ret_ip) { e2k_proc_call(env, wbs * 2, ret_ip, false); diff --git a/target/e2k/helper.h b/target/e2k/helper.h index c0922e4b11..bf8d82b486 100644 --- a/target/e2k/helper.h +++ b/target/e2k/helper.h @@ -15,7 +15,6 @@ DEF_HELPER_1(expand_stacks, void, env) DEF_HELPER_4(call, void, env, i64, int, tl) DEF_HELPER_2(prep_return, i64, env, int) DEF_HELPER_1(return, void, env) -DEF_HELPER_1(signal_return, void, env) DEF_HELPER_4(setwd, void, env, int, int, int) diff --git a/target/e2k/helper_int.c b/target/e2k/helper_int.c index db3600a976..6daa4458b0 100644 --- a/target/e2k/helper_int.c +++ b/target/e2k/helper_int.c @@ -2,6 +2,7 @@ #include "qemu/log.h" #include "qemu/timer.h" #include "cpu.h" +#include "helper-tcg.h" #include "exec/exec-all.h" #include "qemu/host-utils.h" #include "exec/helper-proto.h" @@ -38,11 +39,11 @@ static uint64_t cr_read(CPUE2KState *env, size_t offset) uint64_t HELPER(rrd)(CPUE2KState *env, int idx) { switch (idx) { - case 0x01: return e2k_state_wd(env); /* %wd */ - case 0x07: return e2k_state_psp_hi(env); /* %psp.hi */ - case 0x09: return e2k_state_psp_lo(env); /* %psp.lo */ - case 0x0d: return e2k_state_pcsp_hi(env); /* %pcsp.hi */ - case 0x0f: return e2k_state_pcsp_lo(env); /* %pcsp.lo */ + case 0x01: return env_wd_get(env); /* %wd */ + case 0x07: return env_psp_hi_get(env); /* %psp.hi */ + case 0x09: return env_psp_lo_get(env); /* %psp.lo */ + case 0x0d: return env_pcsp_hi_get(env); /* %pcsp.hi */ + case 0x0f: return env_pcsp_lo_get(env); /* %pcsp.lo */ case 0x13: return 0; /* %pcshtp */ case 0x2c: return env->usd.hi; /* %usd.hi */ case 0x2d: return env->usd.lo; /* %usd.lo */ @@ -52,17 +53,7 @@ uint64_t HELPER(rrd)(CPUE2KState *env, int idx) case 0x57: return cr_read(env, offsetof(E2KCrs, cr1.lo)); /* %cr1.lo */ case 0x80: return env->upsr; /* %upsr */ case 0x81: return env->ip; /* %ip */ - case 0x83: /* %lsr */ - { - uint64_t lsr = env->lsr; - lsr = deposit64(lsr, LSR_LCNT_OFF, LSR_LCNT_LEN, env->lsr_lcnt); - lsr = deposit64(lsr, LSR_ECNT_OFF, LSR_ECNT_LEN, env->lsr_ecnt); - lsr = deposit64(lsr, LSR_VLC_OFF, 1, env->lsr_vlc); - lsr = deposit64(lsr, LSR_OVER_OFF, 1, env->lsr_over); - lsr = deposit64(lsr, LSR_PCNT_OFF, LSR_PCNT_LEN, env->lsr_pcnt); - lsr = deposit64(lsr, LSR_STRMD_OFF, LSR_STRMD_LEN, env->lsr_strmd); - return lsr; - } + case 0x83: return env_lsr_get(env); /* %lsr */ case 0x84: return env->pfpfr.raw; /* %pfpfr */ case 0x85: return env->fpcr.raw; /* %fpcr */ case 0x86: return env->fpsr.raw; /* %fpsr */ @@ -82,13 +73,7 @@ void HELPER(rwd)(CPUE2KState *env, int idx, uint64_t val) env->upsr = val; break; case 0x83: /* %lsr */ - env->lsr = val; - env->lsr_lcnt = extract64(val, LSR_LCNT_OFF, LSR_LCNT_LEN); - env->lsr_ecnt = extract64(val, LSR_ECNT_OFF, LSR_ECNT_LEN); - env->lsr_vlc = extract64(val, LSR_VLC_OFF, 1); - env->lsr_over = extract64(val, LSR_OVER_OFF, 1); - env->lsr_pcnt = extract64(val, LSR_PCNT_OFF, LSR_PCNT_LEN); - env->lsr_strmd = extract64(val, LSR_STRMD_OFF, LSR_STRMD_LEN); + env_lsr_set(env, val); break; case 0x84: /* %pfpfr */ env->pfpfr.raw = val; diff --git a/target/e2k/translate.c b/target/e2k/translate.c index 1a6c453860..1d15b468bd 100644 --- a/target/e2k/translate.c +++ b/target/e2k/translate.c @@ -1407,7 +1407,7 @@ static int64_t get_literal(DisasContext *ctx, uint8_t arg) if (!ctx->bundle.lts_present[i + 1]) { gen_tr_excp_illopc(ctx); } - lit = *(uint64_t *) &ctx->bundle.lts[i]; + lit = ((uint64_t) ctx->bundle.lts[i + 1] << 32) | ctx->bundle.lts[i]; } else { gen_tr_excp_illopc(ctx); } @@ -7658,11 +7658,6 @@ static void e2k_tr_translate_insn(DisasContextBase *db, CPUState *cs) tcg_temp_free_i32(t0); break; } - case E2K_SIGRET_ADDR: - /* fake return from signal handler */ - gen_helper_signal_return(cpu_env); - tcg_gen_exit_tb(NULL, TB_EXIT_IDX0); - break; #endif /* CONFIG_USER_ONLY */ default: {