e2k: Update get/set state regs.
Signed-off-by: Denis Drakhnya <numas13@gmail.com>
This commit is contained in:
parent
21ff5cbef9
commit
48290cb80c
|
@ -38,7 +38,7 @@ static void gen_signal(CPUE2KState *env, int signo, int code, abi_ulong addr)
|
|||
queue_signal(env, signo, QEMU_SI_FAULT, &info);
|
||||
}
|
||||
|
||||
static void stack_expand(CPUE2KState *env, E2KStackState *s)
|
||||
static void stack_expand(CPUE2KState *env, E2KPsp *s)
|
||||
{
|
||||
abi_ulong new_size, new_size_tag;
|
||||
abi_long new_base, new_base_tag = 0;
|
||||
|
@ -98,6 +98,7 @@ void cpu_loop(CPUE2KState *env)
|
|||
break;
|
||||
}
|
||||
case EXCP_ILLEGAL_OPCODE:
|
||||
case EXCP_PRIV_ACTION:
|
||||
gen_signal(env, TARGET_SIGILL, TARGET_ILL_ILLOPC, env->ip);
|
||||
break;
|
||||
case EXCP_ILLEGAL_OPERAND:
|
||||
|
@ -150,6 +151,8 @@ void target_cpu_copy_regs(CPUE2KState *env, struct target_pt_regs *regs)
|
|||
struct image_info *info = ts->info;
|
||||
uint32_t eflags = info->elf_flags;
|
||||
|
||||
env->psr = PSR_NMIE | PSR_SGE | PSR_IE;
|
||||
env->upsr = UPSR_NMIE | UPSR_IE | UPSR_FE;
|
||||
env->ip = regs->ip;
|
||||
env->pcsp = regs->pcsp;
|
||||
env->psp = regs->psp;
|
||||
|
|
|
@ -112,6 +112,8 @@ struct target_sigframe {
|
|||
E2KAauState aau;
|
||||
uint64_t lsr;
|
||||
uint64_t lsr_lcnt;
|
||||
uint32_t ilcr;
|
||||
uint64_t ilcr_lcnt;
|
||||
// FIXME: according to ABI only 16-31 must be saved
|
||||
E2KReg gregs[16];
|
||||
uint8_t gtags[16];
|
||||
|
@ -221,6 +223,8 @@ static void target_setup_frame(int sig, struct target_sigaction *ka,
|
|||
&env->aau, sizeof(env->aau));
|
||||
__put_user(env_lsr_get(env), &frame->lsr);
|
||||
__put_user(env->lsr_lcnt, &frame->lsr_lcnt);
|
||||
__put_user(env->ilcr, &frame->ilcr);
|
||||
__put_user(env->ilcr_lcnt, &frame->ilcr_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),
|
||||
|
@ -323,6 +327,8 @@ long do_rt_sigreturn(CPUE2KState *env)
|
|||
+ offsetof(struct target_sigframe, aau), sizeof(env->aau));
|
||||
__get_user(env->lsr, &frame->lsr);
|
||||
__get_user(env->lsr_lcnt, &frame->lsr_lcnt);
|
||||
__get_user(env->ilcr, &frame->ilcr);
|
||||
__get_user(env->ilcr_lcnt, &frame->ilcr_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
|
||||
|
|
|
@ -18,8 +18,8 @@ static inline void cpu_clone_regs_child(CPUE2KState *env, target_ulong newsp,
|
|||
}
|
||||
|
||||
if (flags & CLONE_VM) {
|
||||
E2KPcsState pcs = { 0 };
|
||||
E2KPsState ps = { 0 };
|
||||
E2KPsp pcs = { 0 };
|
||||
E2KPsp ps = { 0 };
|
||||
E2KCrs crs = { 0 };
|
||||
uint64_t *ps_old, *ps_new;
|
||||
size_t frame_size;
|
||||
|
@ -27,11 +27,10 @@ static inline void cpu_clone_regs_child(CPUE2KState *env, target_ulong newsp,
|
|||
target_ulong ps_base = env->psp.base + env->psp.index;
|
||||
int i;
|
||||
|
||||
e2k_pcs_new(&pcs);
|
||||
e2k_ps_new(&ps);
|
||||
e2k_psp_new(&pcs, E2K_DEFAULT_PCS_SIZE, false);
|
||||
e2k_psp_new(&ps, E2K_DEFAULT_PS_SIZE, true);
|
||||
|
||||
// TODO: size checks and a way to report errors
|
||||
|
||||
// TODO: set a chain info to return to kernel
|
||||
|
||||
pcs.index += sizeof(E2KCrs);
|
||||
|
|
|
@ -31,8 +31,8 @@ struct target_pt_regs {
|
|||
|
||||
// uint64_t tr; // current type register
|
||||
|
||||
E2KPcsState pcsp;
|
||||
E2KPsState psp;
|
||||
E2KPsp pcsp;
|
||||
E2KPsp psp;
|
||||
|
||||
uint32_t psr; // Processor State Register (PSR)
|
||||
uint32_t upsr; // User processor status register (UPSR)
|
||||
|
|
|
@ -1637,23 +1637,14 @@ static abi_ulong e2k_mmap(abi_ulong size)
|
|||
return addr;
|
||||
}
|
||||
|
||||
void e2k_pcs_new(E2KPcsState *pcs)
|
||||
void e2k_psp_new(E2KPsp *psp, unsigned int size, bool tags)
|
||||
{
|
||||
pcs->is_readable = true;
|
||||
pcs->is_writable = true;
|
||||
pcs->index = 0;
|
||||
pcs->size = E2K_DEFAULT_PCS_SIZE;
|
||||
pcs->base = e2k_mmap(pcs->size);
|
||||
}
|
||||
|
||||
void e2k_ps_new(E2KPsState *ps)
|
||||
{
|
||||
ps->is_readable = true;
|
||||
ps->is_writable = true;
|
||||
ps->index = 0;
|
||||
ps->size = E2K_DEFAULT_PS_SIZE;
|
||||
ps->base = e2k_mmap(ps->size);
|
||||
ps->base_tag = e2k_mmap(ps->size / 8);
|
||||
psp->is_readable = true;
|
||||
psp->is_writable = true;
|
||||
psp->index = 0;
|
||||
psp->size = size;
|
||||
psp->base = e2k_mmap(size);
|
||||
psp->base_tag = tags ? e2k_mmap(size / 8) : 0;
|
||||
}
|
||||
|
||||
static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
|
||||
|
@ -1667,8 +1658,8 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i
|
|||
regs->usd_lo = (0x1800UL << 48) | start_stack;
|
||||
regs->usd_hi = (regs->sbr - start_stack) << 32;
|
||||
|
||||
e2k_pcs_new(®s->pcsp);
|
||||
e2k_ps_new(®s->psp);
|
||||
e2k_psp_new(®s->pcsp, E2K_DEFAULT_PCS_SIZE, false);
|
||||
e2k_psp_new(®s->psp, E2K_DEFAULT_PS_SIZE, true);
|
||||
}
|
||||
|
||||
static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUE2KState *env)
|
||||
|
|
|
@ -7045,7 +7045,7 @@ abi_long e2k_copy_to_user_crs(abi_ulong target_crs_addr, E2KCrs *crs)
|
|||
|
||||
static abi_long do_e2k_longjmp2(CPUE2KState *env, struct target_jmp_info *jmp_info)
|
||||
{
|
||||
E2KPcsState jmp_pcsp;
|
||||
E2KPsp jmp_pcsp;
|
||||
E2KCrs crs;
|
||||
int level; /* how many CRs need to restore */
|
||||
int ps_index = env->psp.index;
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
|
||||
//#define DEBUG_FEATURES
|
||||
|
||||
void cpu_e2k_set_id(CPUE2KState *env, unsigned int cpu);
|
||||
void e2k_cpu_dump_state(CPUState *cs, FILE *f, int flags);
|
||||
|
||||
static void e2k_cpu_reset(DeviceState *dev)
|
||||
|
@ -45,6 +44,8 @@ static void e2k_cpu_reset(DeviceState *dev)
|
|||
|
||||
memset(env, 0, offsetof(CPUE2KState, end_reset_fields));
|
||||
|
||||
env->psr = PSR_PM;
|
||||
env->upsr = UPSR_NMIE | UPSR_FE;
|
||||
env->wd.base = 0;
|
||||
env->wd.size = 16;
|
||||
env->wd.psize = 8;
|
||||
|
@ -64,6 +65,12 @@ static void e2k_cpu_reset(DeviceState *dev)
|
|||
|
||||
// FIXME: testing
|
||||
env->idr = 0x3a207; /* mimic 8c */
|
||||
|
||||
// FIXME: correct values
|
||||
env->psp.base = 0x810000;
|
||||
env->psp.size = 0x100000;
|
||||
env->pcsp.base = 0x910000;
|
||||
env->pcsp.size = 0xa10000;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SOFTMMU
|
||||
|
@ -93,13 +100,6 @@ static void cpu_e2k_disas_set_info(CPUState *cs, disassemble_info *info)
|
|||
info->print_insn = print_insn_e2k;
|
||||
}
|
||||
|
||||
|
||||
void cpu_e2k_set_id(CPUE2KState *env, unsigned int cpu)
|
||||
{
|
||||
// TODO: cpu_e2k_set_id
|
||||
qemu_log_mask(LOG_UNIMP, "cpu_e2k_set_id: not implemented\n");
|
||||
}
|
||||
|
||||
/* https://www.altlinux.org/Модели_процессоров_Эльбрус */
|
||||
#define DEFAULT_CPU_MODEL "e8c"
|
||||
static const struct e2k_def_t e2k_defs[] = {
|
||||
|
@ -157,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", 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, " pcsp_lo = 0x%016lx\n", env->pcsp.lo);
|
||||
qemu_fprintf(f, " pcsp_hi = 0x%016lx\n", env->pcsp.hi);
|
||||
qemu_fprintf(f, " psp_lo = 0x%016lx\n", env->psp.lo);
|
||||
qemu_fprintf(f, " psp_hi = 0x%016lx\n", env->psp.hi);
|
||||
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);
|
||||
|
|
408
target/e2k/cpu.h
408
target/e2k/cpu.h
|
@ -28,10 +28,13 @@ void e2k_tcg_initialize(void);
|
|||
*/
|
||||
#define E2K_FORCE_FX true
|
||||
|
||||
#define GEN_MASK(start, len) (((1UL << (len)) - 1) << (start))
|
||||
#define GEN_MASK(start, len) (((1ULL << (len)) - 1) << (start))
|
||||
#define GET_BIT(v, index) (((v) >> (index)) & 1)
|
||||
|
||||
#define MMU_USER_IDX 1
|
||||
#define E2K_VA_SIZE 48
|
||||
#define E2K_VA_MSB (E2K_VA_SIZE - 1)
|
||||
|
||||
#define CPU_RESOLVING_TYPE TYPE_E2K_CPU
|
||||
|
||||
#define E2K_REG_LEN sizeof(uint64_t)
|
||||
|
@ -141,135 +144,107 @@ typedef enum {
|
|||
#define DESC_LO_WRITE_OFF 60
|
||||
#define DESC_LO_WRITE_BIT (1UL << DESC_LO_WRITE_OFF)
|
||||
|
||||
#define PSHTP_IND_OFF 0
|
||||
#define PSHTP_IND_END 11
|
||||
#define PSHTP_IND_LEN (PSHTP_IND_END - PSHTP_IND_OFF + 1)
|
||||
#define PSHTP_FXIND_OFF 16
|
||||
#define PSHTP_FXIND_END 26
|
||||
#define PSHTP_FXIND_LEN (PSHTP_FXIND_END - PSHTP_FXIND_OFF + 1)
|
||||
#define PSHTP_TIND_OFF 32
|
||||
#define PSHTP_TIND_END 42
|
||||
#define PSHTP_TIND_LEN (PSHTP_TIND_END - PSHTP_TIND_OFF + 1)
|
||||
#define PSHTP_FX_OFF 48
|
||||
#define PSHTP_FX_BIT (1UL << PSHTP_FX_OFF)
|
||||
|
||||
#define USD_LO_BASE_OFF 0
|
||||
#define USD_LO_BASE_END 47
|
||||
#define USD_LO_BASE_LEN (USD_LO_BASE_END - USD_LO_BASE_OFF + 1)
|
||||
#define USD_LO_BASE_LEN 48
|
||||
#define USD_LO_PROTECTED_OFF 58
|
||||
#define USD_LO_PROTECTED_BIT (1UL << USD_LO_PROTECTED_OFF)
|
||||
#define USD_LO_PROTECTED_BIT (1ULL << USD_LO_PROTECTED_OFF)
|
||||
#define USD_LO_READ_OFF 59
|
||||
#define USD_LO_READ_BIT (1UL << USD_LO_READ_OFF)
|
||||
#define USD_LO_READ_BIT (1ULL << USD_LO_READ_OFF)
|
||||
#define USD_LO_WRITE_OFF 60
|
||||
#define USD_LO_WRITE_BIT (1UL << USD_LO_WRITE_OFF)
|
||||
#define USD_LO_WRITE_BIT (1ULL << USD_LO_WRITE_OFF)
|
||||
|
||||
#define USD_HI_CURPTR_OFF 0
|
||||
#define USD_HI_CURPTR_END 31
|
||||
#define USD_HI_CURPTR_LEN (USD_HI_CURPTR_END - USD_HI_CURPTR_OFF + 1)
|
||||
#define USD_HI_CURPTR_LEN 32
|
||||
#define USD_HI_SIZE_OFF 32
|
||||
#define USD_HI_SIZE_END 63
|
||||
#define USD_HI_SIZE_LEN (USD_HI_SIZE_END - USD_HI_SIZE_OFF + 1)
|
||||
#define USD_HI_SIZE_LEN 32
|
||||
|
||||
#define CR1_HI_BR_OFF 0
|
||||
#define CR1_HI_BR_END 27
|
||||
#define CR1_HI_BR_LEN (CR1_HI_BR_END - CR1_HI_BR_OFF + 1)
|
||||
#define CR1_HI_BR_LEN 28
|
||||
#define CR1_HI_WDBL_OFF 35
|
||||
#define CR1_HI_WDBL_BIT (1UL << CR1_HI_WDBL_OFF)
|
||||
#define CR1_HI_WDBL_BIT (1ULL << CR1_HI_WDBL_OFF)
|
||||
#define CR1_HI_USSZ_OFF 36
|
||||
#define CR1_HI_USSZ_END 63
|
||||
#define CR1_HI_USSZ_LEN (CR1_HI_USSZ_END - CR1_HI_USSZ_OFF + 1)
|
||||
#define CR1_HI_USSZ_LEN 28
|
||||
|
||||
#define CR1_LO_TR_OFF 0
|
||||
#define CR1_LO_TR_END 14
|
||||
#define CR1_LO_TR_LEN (CR1_LO_TR_END - CR1_LO_TR_OFF + 1)
|
||||
#define CR1_LO_TR_LEN 15
|
||||
#define CR1_LO_EIN_OFF 16
|
||||
#define CR1_LO_EIN_END 23
|
||||
#define CR1_LO_EIN_LEN (CR1_LO_EIN_END - CR1_LO_EIN_OFF + 1)
|
||||
#define CR1_LO_EIN_LEN 8
|
||||
#define CR1_LO_SS_OFF 24
|
||||
#define CR1_LO_SS_BIT (1UL << CR1_LO_SS_OFF)
|
||||
#define CR1_LO_SS_BIT (1ULL << CR1_LO_SS_OFF)
|
||||
#define CR1_LO_WFX_OFF 25
|
||||
#define CR1_LO_WFX_BIT (1UL << CR1_LO_WFX_OFF)
|
||||
#define CR1_LO_WFX_BIT (1ULL << CR1_LO_WFX_OFF)
|
||||
#define CR1_LO_WPSZ_OFF 26
|
||||
#define CR1_LO_WPSZ_END 32
|
||||
#define CR1_LO_WPSZ_LEN (CR1_LO_WPSZ_END - CR1_LO_WPSZ_OFF + 1)
|
||||
#define CR1_LO_WPSZ_LEN 7
|
||||
#define CR1_LO_WBS_OFF 33
|
||||
#define CR1_LO_WBS_END 39
|
||||
#define CR1_LO_WBS_LEN (CR1_LO_WBS_END - CR1_LO_WBS_OFF + 1)
|
||||
#define CR1_LO_WBS_LEN 7
|
||||
#define CR1_LO_CUIR_OFF 40
|
||||
#define CR1_LO_CUIR_END 56
|
||||
#define CR1_LO_CUIR_LEN (CR1_LO_CUIR_END - CR1_LO_CUIR_OFF + 1)
|
||||
#define CR1_LO_CUIR_LEN 17
|
||||
#define CR1_LO_PSR_OFF 57
|
||||
#define CR1_LO_PSR_END 63
|
||||
#define CR1_LO_PSR_LEN (CR1_LO_PSR_END - CR1_LO_PSR_OFF + 1)
|
||||
#define CR1_LO_PSR_LEN 7
|
||||
|
||||
#define BR_RBS_OFF 0 /* based regs window offset */
|
||||
#define BR_RBS_END 5
|
||||
#define BR_RBS_LEN (BR_RBS_END - BR_RBS_OFF + 1)
|
||||
#define BR_RBS_LEN 6
|
||||
#define BR_RSZ_OFF 6 /* based regs window size */
|
||||
#define BR_RSZ_END 11
|
||||
#define BR_RSZ_LEN (BR_RSZ_END - BR_RSZ_OFF + 1)
|
||||
#define BR_RSZ_LEN 6
|
||||
#define BR_RCUR_OFF 12 /* based regs current index */
|
||||
#define BR_RCUR_END 17
|
||||
#define BR_RCUR_LEN (BR_RCUR_END - BR_RCUR_OFF + 1)
|
||||
#define BR_BN_OFF BR_RBS_OFF
|
||||
#define BR_BN_END BR_RCUR_END
|
||||
#define BR_BN_LEN (BR_BN_END - BR_BN_OFF + 1)
|
||||
#define BR_RCUR_LEN 6
|
||||
#define BR_BN_OFF 0
|
||||
#define BR_BN_LEN 18
|
||||
#define BR_PSZ_OFF 18 /* based pregs window size */
|
||||
#define BR_PSZ_END 22
|
||||
#define BR_PSZ_LEN (BR_PSZ_END - BR_PSZ_OFF + 1)
|
||||
#define BR_PSZ_LEN 5
|
||||
#define BR_PCUR_OFF 23 /* based pregs current index */
|
||||
#define BR_PCUR_END 27
|
||||
#define BR_PCUR_LEN (BR_PCUR_END - BR_PCUR_OFF + 1)
|
||||
#define BR_BP_OFF BR_PSZ_OFF
|
||||
#define BR_BP_END BR_PCUR_END
|
||||
#define BR_BP_LEN (BR_BP_END - BR_BP_OFF + 1)
|
||||
#define BR_PCUR_LEN 5
|
||||
#define BR_BP_OFF 18
|
||||
#define BR_BP_LEN 10
|
||||
|
||||
#define BGR_VAL_OFF 0
|
||||
#define BGR_VAL_LEN 8
|
||||
#define BGR_CUR_OFF 8
|
||||
#define BGR_CUR_LEN 3
|
||||
#define BGR_MASK 0x7ff
|
||||
|
||||
#define LSR_LCNT_OFF 0 /* loop counter */
|
||||
#define LSR_LCNT_END 31
|
||||
#define LSR_LCNT_LEN (LSR_LCNT_END - LSR_LCNT_OFF + 1)
|
||||
#define LSR_LCNT_LEN 32
|
||||
#define LSR_ECNT_OFF 32 /* epilogue counter */
|
||||
#define LSR_ECNT_END 36
|
||||
#define LSR_ECNT_LEN (LSR_ECNT_END - LSR_ECNT_OFF + 1)
|
||||
#define LSR_ECNT_LEN 5
|
||||
#define LSR_VLC_OFF 37 /* loop count valid bit */
|
||||
#define LSR_VLC_BIT (1UL << LSR_VLC_OFF)
|
||||
#define LSR_OVER_OFF 38 /* loop count overflow */
|
||||
#define LSR_LDMC_OFF 39 /* loads manual control */
|
||||
#define LSR_LDOVL_OFF 40 /* load overlap */
|
||||
#define LSR_LDOVL_END 47
|
||||
#define LSR_LDOVL_SIZE (LSR_LDOVL_END - LSR_LDOVL_OFF + 1)
|
||||
#define LSR_LDOVL_LEN 8
|
||||
#define LSR_PCNT_OFF 48 /* prologue counter */
|
||||
#define LSR_PCNT_END 52
|
||||
#define LSR_PCNT_LEN (LSR_PCNT_END - LSR_PCNT_OFF + 1)
|
||||
#define LSR_PCNT_LEN 5
|
||||
#define LSR_STRMD_OFF 53 /* store remainder counter */
|
||||
#define LSR_STRMD_END 59
|
||||
#define LSR_STRMD_LEN (LSR_STRMD_END - LSR_STRMD_OFF + 1)
|
||||
#define LSR_SEMC_OFF /* side effects manual control */
|
||||
#define LSR_ILCR_MASK 0x1f001fffffffffUL
|
||||
#define LSR_STRMD_LEN 7
|
||||
#define LSR_SEMC_OFF 60 /* side effects manual control */
|
||||
#define ILCR_MASK 0x1f001f
|
||||
|
||||
#define UPSR_FE_OFF 0 /* floating point enable */
|
||||
#define UPSR_FE_BIT 1
|
||||
#define UPSR_SE_OFF 1 /* supervisor mode enable (only for Intel) */
|
||||
#define UPSR_SE_BIT (1 << UPSR_SE_OFF)
|
||||
#define UPSR_AC_OFF 2 /* not-aligned access control */
|
||||
#define UPSR_AC_BIT (1 << UPSR_AC_OFF)
|
||||
#define UPSR_DI_OFF 3 /* delayed interrupt (only for Intel) */
|
||||
#define UPSR_DI_BIT (1 << UPSR_DI_OFF)
|
||||
#define UPSR_WP_OFF 4 /* write protection (only for Intel) */
|
||||
#define UPSR_WP_BIT (1 << UPSR_WP_OFF)
|
||||
#define UPSR_IE_OFF 5 /* interrupt enable */
|
||||
#define UPSR_IE_BIT (1 << UPSR_IE_OFF)
|
||||
#define UPSR_A20_OFF 6 /* emulation of 1 Mb memory (only for Intel) */
|
||||
#define UPSR_A20_BIT (1 << UPSR_A20_OFF)
|
||||
#define UPSR_NMIE_OFF 7 /* not masked interrupt enable */
|
||||
#define UPSR_NMIE_BIT (1 << UPSR_NMIE_OFF)
|
||||
/* next field of register exist only on E3S/ES2/E2S/E8C/E1C+ CPUs */
|
||||
#define UPSR_FSM_OFF 8 /* floating comparison mode flag */
|
||||
/* 1 - compatible with x86/x87 */
|
||||
#define UPSR_FSM_BIT (1 << UPSR_FSM_OFF)
|
||||
#define UPSR_IMPT_OFF 9 /* ignore Memory Protection Table flag */
|
||||
#define UPSR_IMPT_BIT (1 << UPSR_IMPT_OFF)
|
||||
#define UPSR_IUC_OFF 10 /* ignore access right for uncached pages */
|
||||
#define UPSR_IUC_BIT (1 << UPSR_IUC_OFF)
|
||||
#define PSR_PM 0x01U /* privileged mode */
|
||||
#define PSR_IE 0x02U
|
||||
#define PSR_SGE 0x04U
|
||||
#define PSR_LW 0x08U
|
||||
#define PSR_UIE 0x10U
|
||||
#define PSR_NMIE 0x20U
|
||||
#define PSR_UNMIE 0x40U
|
||||
#define PSR_MASK 0x7fU
|
||||
|
||||
#define UPSR_FE 0x01U /* floating point enable */
|
||||
#define UPSR_SE 0x02U /* supervisor mode enable (only for Intel) */
|
||||
#define UPSR_AC 0x04U /* not-aligned access control */
|
||||
#define UPSR_DI 0x08U /* delayed interrupt (only for Intel) */
|
||||
#define UPSR_WP 0x10U /* write protection (only for Intel) */
|
||||
#define UPSR_IE 0x20U /* interrupt enable */
|
||||
#define UPSR_A20 0x40U /* emulation of 1 Mb memory (only for Intel) */
|
||||
#define UPSR_NMIE 0x80U /* not masked interrupt enable */
|
||||
#define UPSR_FSM 0x100U /* only on E3S/ES2/E2S/E8C/E1C+ CPUs */
|
||||
/* floating comparison mode flag */
|
||||
/* 1 - compatible with x86/x87 */
|
||||
#define UPSR_IMPT 0x200U /* ignore Memory Protection Table flag */
|
||||
#define UPSR_IUC 0x400U /* ignore access right for uncached pages */
|
||||
#define UPSR_MASK 0x7ff
|
||||
|
||||
#define CUIR_MASK 0x1ffff
|
||||
|
||||
#define IDR_MDL_OFF 0 /* CPU model number */
|
||||
#define IDR_MDL_END 7
|
||||
|
@ -344,6 +319,93 @@ typedef enum {
|
|||
#endif
|
||||
} Exception;
|
||||
|
||||
typedef enum {
|
||||
SR_PSR = 0x00,
|
||||
SR_WD = 0x01,
|
||||
SR_CORE_MODE = 0x04,
|
||||
SR_CWD = 0x06,
|
||||
SR_PSP_HI = 0x07,
|
||||
SR_PSP_LO = 0x09,
|
||||
SR_PSHTP = 0x0b,
|
||||
SR_PCSP_HI = 0x0d,
|
||||
SR_PCSP_LO = 0x0f,
|
||||
SR_PCSHTP = 0x13,
|
||||
SR_CTPR1 = 0x15,
|
||||
SR_CTPR2 = 0x16,
|
||||
SR_CTPR3 = 0x17,
|
||||
SR_SBR = 0x1e,
|
||||
SR_CUTD = 0x21,
|
||||
SR_EIR = 0x23,
|
||||
SR_TSD = 0x24,
|
||||
SR_CUIR = 0x25,
|
||||
SR_OSCUD_HI = 0x26,
|
||||
SR_OSCUD_LO = 0x27,
|
||||
SR_OSGD_HI = 0x28,
|
||||
SR_OSGD_LO = 0x29,
|
||||
SR_OSEM = 0x2a,
|
||||
SR_USD_HI = 0x2c,
|
||||
SR_USD_LO = 0x2d,
|
||||
SR_TR = 0x2e,
|
||||
SR_OSR0 = 0x2f,
|
||||
SR_CUD_HI = 0x30,
|
||||
SR_CUD_LO = 0x31,
|
||||
SR_GD_HI = 0x32,
|
||||
SR_GD_LO = 0x33,
|
||||
SR_CS_HI = 0x34,
|
||||
SR_CS_LO = 0x35,
|
||||
SR_DS_HI = 0x36,
|
||||
SR_DS_LO = 0x37,
|
||||
SR_ES_HI = 0x38,
|
||||
SR_ES_LO = 0x39,
|
||||
SR_FS_HI = 0x3a,
|
||||
SR_FS_LO = 0x3b,
|
||||
SR_GS_HI = 0x3c,
|
||||
SR_GS_LO = 0x3d,
|
||||
SR_SS_HI = 0x3e,
|
||||
SR_SS_LO = 0x3f,
|
||||
SR_DIBCR = 0x40,
|
||||
SR_DIMCR = 0x41,
|
||||
SR_DIBSR = 0x42,
|
||||
SR_DTCR = 0x43,
|
||||
SR_DIBAR0 = 0x48,
|
||||
SR_DIBAR1 = 0x49,
|
||||
SR_DIBAR2 = 0x4a,
|
||||
SR_DIBAR3 = 0x4b,
|
||||
SR_DIMAR0 = 0x4c,
|
||||
SR_DIMAR1 = 0x4d,
|
||||
SR_DTRAF = 0x4e,
|
||||
SR_DTART = 0x4f,
|
||||
SR_CR0_HI = 0x51,
|
||||
SR_CR0_LO = 0x53,
|
||||
SR_CR1_HI = 0x55,
|
||||
SR_CR1_LO = 0x57,
|
||||
SR_SCLKM1 = 0x70,
|
||||
SR_SCLKM2 = 0x71,
|
||||
SR_CU_HW0 = 0x78,
|
||||
SR_UPSR = 0x80,
|
||||
SR_IP = 0x81,
|
||||
SR_NIP = 0x82,
|
||||
SR_LSR = 0x83,
|
||||
SR_PFPFR = 0x84,
|
||||
SR_FPCR = 0x85,
|
||||
SR_FPSR = 0x86,
|
||||
SR_ILCR = 0x87,
|
||||
SR_BR = 0x88,
|
||||
SR_BGR = 0x89,
|
||||
SR_IDR = 0x8A,
|
||||
SR_CLKR = 0x90,
|
||||
SR_RNDPR = 0x91,
|
||||
SR_SCLKR = 0x92,
|
||||
SR_TIR_HI = 0x9C,
|
||||
SR_TIR_LO = 0x9D,
|
||||
SR_RPR = 0xA0,
|
||||
SR_SBBP = 0xA1,
|
||||
SR_RPR_HI = 0xA2,
|
||||
SR_UPSRM = 0xC0,
|
||||
SR_LSR1 = 0xC3,
|
||||
SR_ILCR1 = 0xC7,
|
||||
} StateReg;
|
||||
|
||||
struct e2k_def_t {
|
||||
const char *name;
|
||||
const char *canonical_name;
|
||||
|
@ -436,8 +498,11 @@ typedef struct {
|
|||
};
|
||||
uint64_t hi;
|
||||
};
|
||||
/* FIXME: HACK: pointer to tag storage */
|
||||
target_ulong base_tag;
|
||||
} E2KStackState, E2KPsState, E2KPcsState;
|
||||
} E2KPsp;
|
||||
|
||||
#define E2K_PSP_LO_MASK (GEN_MASK(56, 8) | GEN_MASK(0, E2K_VA_SIZE))
|
||||
|
||||
typedef struct {
|
||||
int32_t base;
|
||||
|
@ -659,22 +724,24 @@ typedef struct {
|
|||
union {
|
||||
uint64_t lo;
|
||||
struct {
|
||||
uint64_t base: 48;
|
||||
uint64_t unused1: 10;
|
||||
uint64_t protected: 1;
|
||||
uint64_t read: 1;
|
||||
uint64_t write: 1;
|
||||
uint64_t unsued2: 3;
|
||||
uint64_t base : E2K_VA_SIZE; /* [47: 0] */
|
||||
uint64_t unused1 : 57 - E2K_VA_MSB; /* [57:48] */
|
||||
uint64_t protected : 1; /* [58] */
|
||||
uint64_t read : 1; /* [59] */
|
||||
uint64_t write : 1; /* [60] */
|
||||
uint64_t unsued2 : 3; /* [63:61] */
|
||||
};
|
||||
};
|
||||
union {
|
||||
uint64_t hi;
|
||||
struct {
|
||||
uint64_t curptr: 32;
|
||||
uint64_t size: 32;
|
||||
uint64_t curptr : 32; /* [31: 0] */
|
||||
uint64_t size : 32; /* [63:32] */
|
||||
};
|
||||
};
|
||||
} E2KUserStackDesc;
|
||||
} E2KRwap;
|
||||
|
||||
#define E2K_RWAP_LO_MASK (GEN_MASK(58, 3) | GEN_MASK(0, E2K_VA_SIZE))
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -713,33 +780,37 @@ typedef union {
|
|||
} E2KReg;
|
||||
|
||||
typedef struct CPUArchState {
|
||||
/* register file */
|
||||
uint8_t tags[E2K_REG_COUNT]; /* registers tags */
|
||||
E2KReg regs[E2K_REG_COUNT]; /* low parts of registers */
|
||||
uint64_t pregs; /* predicate file */
|
||||
target_ulong ip; /* instruction address */
|
||||
|
||||
/* big constant values */
|
||||
E2KReg tmp[12];
|
||||
/* pre saved registers */
|
||||
E2KReg tmp_saved[6];
|
||||
/* alops results */
|
||||
E2KReg al_result[12];
|
||||
|
||||
/* DAM */
|
||||
E2KDamEntry dam[32];
|
||||
|
||||
/* Procedure chain info = cr0_lo, cr0_hi, cr1_lo, cr1_hi */
|
||||
E2KPcsState pcsp;
|
||||
|
||||
/* Procedure stack pointer (for regs) */
|
||||
E2KPsState psp;
|
||||
/* Registers Tags File */
|
||||
uint8_t tags[E2K_REG_COUNT];
|
||||
/* Registers File */
|
||||
E2KReg regs[E2K_REG_COUNT];
|
||||
/* Predicate Registers File */
|
||||
uint64_t pregs;
|
||||
/* Instruction Address */
|
||||
target_ulong ip;
|
||||
/* Next Instruction Address */
|
||||
target_ulong nip;
|
||||
|
||||
/* Procedure Chain Stack Pointer (control registers) */
|
||||
E2KPsp pcsp;
|
||||
/* Procedure Stack Pointer (window registers) */
|
||||
E2KPsp psp;
|
||||
/* Non-Protected User Stack Pointer */
|
||||
E2KRwap usd;
|
||||
/* Non-Protected User Stack Base address */
|
||||
uint64_t sbr;
|
||||
/* Procedure Registers Window state */
|
||||
E2KWdState wd;
|
||||
/* Flag to clear the upper half of the register for 32-bit operations */
|
||||
uint32_t wdbl;
|
||||
/* Based Registers Window state */
|
||||
E2KBnState bn;
|
||||
/* Based Predicate Registers Window state */
|
||||
E2KBpState bp;
|
||||
/* Based Global Registers Window state */
|
||||
uint32_t bgr;
|
||||
|
||||
/* loop status register */
|
||||
/* Loop Status Register */
|
||||
uint64_t lsr;
|
||||
uint64_t lsr_lcnt;
|
||||
uint32_t lsr_ecnt;
|
||||
|
@ -748,40 +819,84 @@ typedef struct CPUArchState {
|
|||
uint32_t lsr_pcnt;
|
||||
uint32_t lsr_strmd;
|
||||
|
||||
uint64_t sbr;
|
||||
E2KUserStackDesc usd;
|
||||
/* Initial Loop Counter Register */
|
||||
uint32_t ilcr;
|
||||
uint64_t ilcr_lcnt;
|
||||
|
||||
/* control registers */
|
||||
E2KCtpr ctprs[3]; // Control Transfer Preparation Register (CTPR)
|
||||
/* Control Transfer Preparation Register (CTPR) */
|
||||
E2KCtpr ctprs[3];
|
||||
/* Control Transfer Condition */
|
||||
target_ulong ct_cond;
|
||||
|
||||
target_ulong nip; /* next instruction address */
|
||||
|
||||
uint64_t upsr;
|
||||
uint32_t psr;
|
||||
uint32_t upsr;
|
||||
uint32_t cuir;
|
||||
/* System Register */
|
||||
uint64_t osr0;
|
||||
uint64_t idr;
|
||||
uint64_t core_mode;
|
||||
|
||||
E2KPfpfr pfpfr; // Packed Floating Point Flag Register (PFPFR)
|
||||
E2KFpsrState fpsr; // Floating point state register (FPSR)
|
||||
E2KFpcrState fpcr; // Floating point control register (FPCR)
|
||||
/* Packed Floating Point Flag Register (PFPFR) */
|
||||
E2KPfpfr pfpfr;
|
||||
/* Floating point state register (FPSR) */
|
||||
E2KFpsrState fpsr;
|
||||
/* Floating point control register (FPCR) */
|
||||
E2KFpcrState fpcr;
|
||||
|
||||
float_status fp_status;
|
||||
float_status fx_status;
|
||||
|
||||
/* OS Compilation Unit Descriptor */
|
||||
E2KRwap oscud;
|
||||
/* OS Compilation Unit Globals Descriptor */
|
||||
E2KRwap osgd;
|
||||
|
||||
/* User Compilation Unit Descriptor */
|
||||
E2KRwap cud;
|
||||
/* User Compilation Unit Globals Descriptor */
|
||||
E2KRwap gd;
|
||||
|
||||
/* Segment Registers */
|
||||
E2KRwap cs;
|
||||
E2KRwap ds;
|
||||
E2KRwap es;
|
||||
E2KRwap fs;
|
||||
E2KRwap gs;
|
||||
E2KRwap ss;
|
||||
|
||||
/* Array Access Unit State */
|
||||
E2KAauState aau;
|
||||
|
||||
/* DAM */
|
||||
E2KDamEntry dam[32];
|
||||
|
||||
/*
|
||||
* Internal use
|
||||
*/
|
||||
|
||||
/* TODO */
|
||||
int interrupt_index;
|
||||
|
||||
/* internal use */
|
||||
uint32_t is_bp; /* breakpoint flag */
|
||||
uint64_t last_val0; /* ld mas=7 + st mas=2 */
|
||||
uint64_t last_val1; /* ld mas=7 + st mas=2 */
|
||||
/* 32/64-bit scalar/packed float status */
|
||||
float_status fp_status;
|
||||
/* 80-bit float status */
|
||||
float_status fx_status;
|
||||
|
||||
/* zeroing upper register half for 32-bit instructions */
|
||||
uint32_t wdbl;
|
||||
/* Temporary storage for big constant values */
|
||||
E2KReg tmp[12];
|
||||
/* Temporary storage for pre saved registers */
|
||||
E2KReg tmp_saved[6];
|
||||
/* Temporary storage for empty and temporary results of alops */
|
||||
E2KReg al_result[12];
|
||||
|
||||
/* breakpoint flag */
|
||||
uint32_t is_bp;
|
||||
|
||||
/* FIXME: DAM? ld mas=7 + st mas=2 */
|
||||
uint64_t last_val0;
|
||||
uint64_t last_val1;
|
||||
|
||||
/* Fields up to this point are cleared by a CPU reset */
|
||||
struct {} end_reset_fields;
|
||||
|
||||
/* ISA version */
|
||||
uint32_t version;
|
||||
/* Force alop to preserve the destination register before writing to it.
|
||||
* Default: false */
|
||||
|
@ -838,8 +953,9 @@ bool e2k_cpu_tlb_fill(CPUState *cpu, vaddr address, int size,
|
|||
bool probe, uintptr_t retaddr);
|
||||
void e2k_update_fp_status(CPUE2KState *env);
|
||||
void e2k_update_fx_status(CPUE2KState *env);
|
||||
void e2k_pcs_new(E2KPcsState *pcs);
|
||||
void e2k_ps_new(E2KPsState *ps);
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
void e2k_psp_new(E2KPsp *psp, unsigned int size, bool tags);
|
||||
#endif
|
||||
void e2k_proc_call(CPUE2KState *env, int base, target_ulong ret_ip,
|
||||
bool force_fx);
|
||||
void e2k_proc_return(CPUE2KState *env, bool force_fx);
|
||||
|
|
|
@ -52,22 +52,22 @@ int e2k_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
|
|||
}
|
||||
|
||||
switch (n) {
|
||||
case 35: return gdb_get_reg64(mem_buf, 0); // psr
|
||||
case 35: return gdb_get_reg64(mem_buf, env->psr); // psr
|
||||
case 36: return gdb_get_reg64(mem_buf, env->upsr); // upsr
|
||||
case 37: return gdb_get_reg64(mem_buf, 0); // oscud_lo
|
||||
case 38: return gdb_get_reg64(mem_buf, 0); // oscud_hi
|
||||
case 39: return gdb_get_reg64(mem_buf, 0); // osgd_lo
|
||||
case 40: return gdb_get_reg64(mem_buf, 0); // osgd_hi
|
||||
case 37: return gdb_get_reg64(mem_buf, env->oscud.lo); // oscud_lo
|
||||
case 38: return gdb_get_reg64(mem_buf, env->oscud.hi); // oscud_hi
|
||||
case 39: return gdb_get_reg64(mem_buf, env->osgd.lo); // osgd_lo
|
||||
case 40: return gdb_get_reg64(mem_buf, env->osgd.hi); // osgd_hi
|
||||
case 41: return gdb_get_reg64(mem_buf, 0); // osem
|
||||
case 42: return gdb_get_reg64(mem_buf, 0); // osr0
|
||||
case 43: return gdb_get_reg64(mem_buf, 0); // pfpfr
|
||||
case 44: return gdb_get_reg64(mem_buf, 0); // fpcr
|
||||
case 45: return gdb_get_reg64(mem_buf, 0); // fpsr
|
||||
case 42: return gdb_get_reg64(mem_buf, env->osr0); // osr0
|
||||
case 43: return gdb_get_reg64(mem_buf, env->pfpfr.raw); // pfpfr
|
||||
case 44: return gdb_get_reg64(mem_buf, env->fpcr.raw); // fpcr
|
||||
case 45: return gdb_get_reg64(mem_buf, env->fpsr.raw); // fpsr
|
||||
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, env_psp_lo_get(env)); // psp_lo
|
||||
case 50: return gdb_get_reg64(mem_buf, env_psp_hi_get(env)); // psp_hi
|
||||
case 49: return gdb_get_reg64(mem_buf, env->psp.lo); // psp_lo
|
||||
case 50: return gdb_get_reg64(mem_buf, env->psp.hi); // 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
|
||||
|
@ -80,25 +80,25 @@ 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, env_pcsp_lo_get(env)); // pcsp_lo
|
||||
case 58: return gdb_get_reg64(mem_buf, env_pcsp_hi_get(env)); // pcsp_hi
|
||||
case 57: return gdb_get_reg64(mem_buf, env->pcsp.lo); // pcsp_lo
|
||||
case 58: return gdb_get_reg64(mem_buf, env->pcsp.hi); // 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
|
||||
case 62: return gdb_get_reg64(mem_buf, 0); // gd_lo
|
||||
case 63: return gdb_get_reg64(mem_buf, 0); // gd_hi
|
||||
case 64: return gdb_get_reg64(mem_buf, 0); // cs_lo
|
||||
case 65: return gdb_get_reg64(mem_buf, 0); // cs_hi
|
||||
case 66: return gdb_get_reg64(mem_buf, 0); // ds_lo
|
||||
case 67: return gdb_get_reg64(mem_buf, 0); // ds_hi
|
||||
case 68: return gdb_get_reg64(mem_buf, 0); // es_lo
|
||||
case 69: return gdb_get_reg64(mem_buf, 0); // es_hi
|
||||
case 70: return gdb_get_reg64(mem_buf, 0); // fs_lo
|
||||
case 71: return gdb_get_reg64(mem_buf, 0); // fs_hi
|
||||
case 72: return gdb_get_reg64(mem_buf, 0); // gs_lo
|
||||
case 73: return gdb_get_reg64(mem_buf, 0); // gs_hi
|
||||
case 74: return gdb_get_reg64(mem_buf, 0); // ss_lo
|
||||
case 75: return gdb_get_reg64(mem_buf, 0); // ss_hi
|
||||
case 60: return gdb_get_reg64(mem_buf, env->cud.lo); // cud_lo
|
||||
case 61: return gdb_get_reg64(mem_buf, env->cud.hi); // cud_hi
|
||||
case 62: return gdb_get_reg64(mem_buf, env->gd.lo); // gd_lo
|
||||
case 63: return gdb_get_reg64(mem_buf, env->gd.hi); // gd_hi
|
||||
case 64: return gdb_get_reg64(mem_buf, env->cs.lo); // cs_lo
|
||||
case 65: return gdb_get_reg64(mem_buf, env->cs.hi); // cs_hi
|
||||
case 66: return gdb_get_reg64(mem_buf, env->ds.lo); // ds_lo
|
||||
case 67: return gdb_get_reg64(mem_buf, env->ds.hi); // ds_hi
|
||||
case 68: return gdb_get_reg64(mem_buf, env->es.lo); // es_lo
|
||||
case 69: return gdb_get_reg64(mem_buf, env->es.hi); // es_hi
|
||||
case 70: return gdb_get_reg64(mem_buf, env->fs.lo); // fs_lo
|
||||
case 71: return gdb_get_reg64(mem_buf, env->fs.hi); // fs_hi
|
||||
case 72: return gdb_get_reg64(mem_buf, env->gs.lo); // gs_lo
|
||||
case 73: return gdb_get_reg64(mem_buf, env->gs.hi); // gs_hi
|
||||
case 74: return gdb_get_reg64(mem_buf, env->ss.lo); // ss_lo
|
||||
case 75: return gdb_get_reg64(mem_buf, env->ss.hi); // ss_hi
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -178,9 +178,9 @@ int e2k_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
|
|||
case 333: return gdb_get_reg64(mem_buf, 0); // dtart
|
||||
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 336: return gdb_get_reg64(mem_buf, env->bgr); // bgr
|
||||
case 337: return gdb_get_reg64(mem_buf, 0); // unk
|
||||
case 338: return gdb_get_reg64(mem_buf, 0); // nip
|
||||
case 338: return gdb_get_reg64(mem_buf, env->nip); // nip
|
||||
case 339: return gdb_get_reg64(mem_buf, env->ctprs[0].raw); // ctpr1
|
||||
case 340: return gdb_get_reg64(mem_buf, env->ctprs[1].raw); // ctpr2
|
||||
case 341: return gdb_get_reg64(mem_buf, env->ctprs[2].raw); // ctpr3
|
||||
|
@ -189,17 +189,8 @@ int e2k_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
|
|||
case 344: return gdb_get_reg64(mem_buf, 0); // cutd
|
||||
case 345: return gdb_get_reg64(mem_buf, 0); // cuir
|
||||
case 346: return gdb_get_reg64(mem_buf, 0); // tsd
|
||||
case 347: { // 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 gdb_get_reg64(mem_buf, lsr);
|
||||
}
|
||||
case 348: return gdb_get_reg64(mem_buf, env->lsr & LSR_ILCR_MASK); // ilcr
|
||||
case 347: return gdb_get_reg64(mem_buf, env_lsr_get(env)); /* lsr */
|
||||
case 348: return gdb_get_reg64(mem_buf, env_ilcr_get(env)); /* ilcr */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -328,8 +319,8 @@ static int gdb_set_v2(CPUE2KState *env, uint8_t *mem_buf, int n)
|
|||
static int gdb_get_v3(CPUE2KState *env, GByteArray *buf, int n)
|
||||
{
|
||||
if (n == 0) {
|
||||
/* TODO: core_mode */
|
||||
return gdb_get_reg64(buf, 0);
|
||||
/* core_mode */
|
||||
return gdb_get_reg64(buf, env->core_mode);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -344,13 +335,16 @@ static int gdb_set_v3(CPUE2KState *env, uint8_t *mem_buf, int n)
|
|||
static int gdb_get_v5(CPUE2KState *env, GByteArray *buf, int n)
|
||||
{
|
||||
if (n == 0) {
|
||||
/* lsr1 */
|
||||
return gdb_get_reg64(buf, env->lsr_lcnt);
|
||||
} else if (n == 1) {
|
||||
// TODO: ilcr1
|
||||
return gdb_get_reg64(buf, 0);
|
||||
/* ilcr1 */
|
||||
return gdb_get_reg64(buf, env->ilcr_lcnt);
|
||||
} else if (n >= 2 && n < 34) {
|
||||
/* xgN (upper 64-bit) */
|
||||
return gdb_get_reg64(buf, env->regs[E2K_NR_COUNT + n - 2].hi);
|
||||
} else if (n >= 34 && n < 66) {
|
||||
/* qpgN tags */
|
||||
return gdb_get_reg8(buf, env->tags[E2K_NR_COUNT + n - 34]);
|
||||
}
|
||||
|
||||
|
|
|
@ -35,37 +35,10 @@
|
|||
#define ident(x) (x)
|
||||
|
||||
/* helper.c */
|
||||
void G_NORETURN raise_exception(CPUE2KState *env, int exception_index);
|
||||
void G_NORETURN raise_exception_ra(CPUE2KState *env, int exception_index,
|
||||
void G_NORETURN raise_exception(CPUE2KState *desc, int exception_index);
|
||||
void G_NORETURN raise_exception_ra(CPUE2KState *desc, 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;
|
||||
|
@ -137,4 +110,35 @@ static inline void env_lsr_set(CPUE2KState *env, uint64_t val)
|
|||
env->lsr_strmd = extract64(val, LSR_STRMD_OFF, LSR_STRMD_LEN);
|
||||
}
|
||||
|
||||
static inline uint64_t env_ilcr_get(CPUE2KState *env)
|
||||
{
|
||||
return ((uint64_t) env->ilcr << LSR_ECNT_OFF)
|
||||
| (env->ilcr_lcnt & GEN_MASK(0, LSR_LCNT_LEN));
|
||||
}
|
||||
|
||||
static inline void env_ilcr_set(CPUE2KState *env, uint64_t value)
|
||||
{
|
||||
env->ilcr = (value >> LSR_ECNT_OFF) & ILCR_MASK;
|
||||
env->ilcr_lcnt = value & GEN_MASK(0, LSR_LCNT_LEN);
|
||||
}
|
||||
|
||||
static inline uint64_t env_usd_lo_get(CPUE2KState *env)
|
||||
{
|
||||
uint64_t r = 0;
|
||||
|
||||
r = deposit64(r, USD_LO_BASE_OFF, USD_LO_BASE_LEN, env->usd.base);
|
||||
r |= env->usd.protected ? USD_LO_PROTECTED_BIT : 0;
|
||||
r |= env->usd.read ? USD_LO_READ_BIT : 0;
|
||||
r |= env->usd.write ? USD_LO_WRITE_BIT : 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
static inline void env_usd_lo_set(CPUE2KState *env, uint64_t value)
|
||||
{
|
||||
env->usd.base = extract64(value, USD_LO_BASE_OFF, USD_LO_BASE_LEN);
|
||||
env->usd.protected = (value & USD_LO_PROTECTED_BIT) != 0;
|
||||
env->usd.read = (value & USD_LO_READ_BIT) != 0;
|
||||
env->usd.write = (value & USD_LO_WRITE_BIT) != 0;
|
||||
}
|
||||
|
||||
#endif /* E2K_HELPER_TCG_H */
|
||||
|
|
|
@ -165,6 +165,8 @@ 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.psr = env->psr;
|
||||
crs.cr1.cuir = env->cuir;
|
||||
crs.cr1.br = env_br_get(env);
|
||||
crs.cr1.ussz = env->usd.size >> 4;
|
||||
|
||||
|
@ -189,6 +191,8 @@ void e2k_proc_return(CPUE2KState *env, bool force_fx)
|
|||
env->pregs = crs.cr0_lo;
|
||||
env->ip = crs.cr0_hi & ~7;
|
||||
env_br_set(env, crs.cr1.br);
|
||||
env->cuir = crs.cr1.cuir;
|
||||
env->psr = crs.cr1.psr;
|
||||
env->wd.size = env->wd.psize + base;
|
||||
env->wd.psize = crs.cr1.wpsz * 2;
|
||||
env->wd.fx = crs.cr1.wfx;
|
||||
|
|
|
@ -30,9 +30,8 @@ DEF_HELPER_4(dam_unlock_addr, int, env, i64, int, int)
|
|||
|
||||
DEF_HELPER_2(getsp, i64, env, i32)
|
||||
|
||||
DEF_HELPER_FLAGS_2(rrd, TCG_CALL_NO_WG_SE, i64, env, int)
|
||||
DEF_HELPER_3(rwd, void, env, int, i64)
|
||||
DEF_HELPER_3(rws, void, env, int, i32)
|
||||
DEF_HELPER_FLAGS_2(state_reg_get, TCG_CALL_NO_WG_SE, i64, env, int)
|
||||
DEF_HELPER_3(state_reg_set, void, env, i64, int)
|
||||
|
||||
DEF_HELPER_FLAGS_2(sxt, TCG_CALL_NO_RWG_SE, i64, i32, i32)
|
||||
DEF_HELPER_FLAGS_2(clmull, TCG_CALL_NO_RWG_SE, i64, i64, i64)
|
||||
|
|
|
@ -19,83 +19,283 @@ static uint64_t cr_read(CPUE2KState *env, size_t offset)
|
|||
return cpu_ldq_le_data(env, addr);
|
||||
}
|
||||
|
||||
uint64_t HELPER(rrd)(CPUE2KState *env, int idx)
|
||||
uint64_t HELPER(state_reg_get)(CPUE2KState *env, int index)
|
||||
{
|
||||
switch (idx) {
|
||||
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 */
|
||||
case 0x51: return cr_read(env, offsetof(E2KCrs, cr0_hi)); /* %cr0.hi */
|
||||
case 0x53: return cr_read(env, offsetof(E2KCrs, cr0_lo)); /* %cr0.lo */
|
||||
case 0x55: return cr_read(env, offsetof(E2KCrs, cr1.hi)); /* %cr1.hi */
|
||||
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: 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 */
|
||||
case 0x8a: return env->idr; /* %idr */
|
||||
case 0x90: return cpu_get_host_ticks(); /* %clkr */
|
||||
case 0xc3: return env->lsr_lcnt; /* %lsr1 */
|
||||
switch (index) {
|
||||
case SR_PSR: return env->psr;
|
||||
case SR_WD: return env_wd_get(env);
|
||||
case SR_CORE_MODE: return env->core_mode;
|
||||
case SR_CWD: return 0; /* ignore */
|
||||
case SR_PSP_HI: return env->psp.hi;
|
||||
case SR_PSP_LO: return env->psp.lo;
|
||||
case SR_PSHTP: return 0; /* ignore */
|
||||
case SR_PCSP_HI: return env->pcsp.hi;
|
||||
case SR_PCSP_LO: return env->pcsp.lo;
|
||||
case SR_PCSHTP: return 0; /* ignore */
|
||||
case SR_CTPR1: return env->ctprs[0].raw;
|
||||
case SR_CTPR2: return env->ctprs[1].raw;
|
||||
case SR_CTPR3: return env->ctprs[2].raw;
|
||||
case SR_SBR: return env->sbr;
|
||||
case SR_CUTD:
|
||||
case SR_EIR:
|
||||
case SR_TSD: goto todo;
|
||||
case SR_CUIR: return env->cuir;
|
||||
case SR_OSCUD_HI: return env->oscud.hi;
|
||||
case SR_OSCUD_LO: return env->oscud.lo;
|
||||
case SR_OSGD_HI: return env->osgd.hi;
|
||||
case SR_OSGD_LO: return env->osgd.lo;
|
||||
case SR_OSEM: goto todo;
|
||||
case SR_USD_HI: return env->usd.hi;
|
||||
case SR_USD_LO: return env->usd.lo;
|
||||
case SR_TR: goto todo;
|
||||
case SR_OSR0: return env->osr0;
|
||||
case SR_CUD_HI: return env->cud.hi;
|
||||
case SR_CUD_LO: return env->cud.lo;
|
||||
case SR_GD_HI: return env->gd.hi;
|
||||
case SR_GD_LO: return env->gd.lo;
|
||||
case SR_CS_HI: return env->cs.hi;
|
||||
case SR_CS_LO: return env->cs.lo;
|
||||
case SR_DS_HI: return env->ds.hi;
|
||||
case SR_DS_LO: return env->ds.lo;
|
||||
case SR_ES_HI: return env->es.hi;
|
||||
case SR_ES_LO: return env->es.lo;
|
||||
case SR_FS_HI: return env->fs.hi;
|
||||
case SR_FS_LO: return env->fs.lo;
|
||||
case SR_GS_HI: return env->gs.hi;
|
||||
case SR_GS_LO: return env->gs.lo;
|
||||
case SR_SS_HI: return env->ss.hi;
|
||||
case SR_SS_LO: return env->ss.lo;
|
||||
case SR_DIBCR:
|
||||
case SR_DIMCR:
|
||||
case SR_DIBSR:
|
||||
case SR_DTCR:
|
||||
case SR_DIBAR0:
|
||||
case SR_DIBAR1:
|
||||
case SR_DIBAR2:
|
||||
case SR_DIBAR3:
|
||||
case SR_DIMAR0:
|
||||
case SR_DIMAR1:
|
||||
case SR_DTRAF:
|
||||
case SR_DTART: goto todo;
|
||||
case SR_CR0_HI: return cr_read(env, offsetof(E2KCrs, cr0_hi));
|
||||
case SR_CR0_LO: return cr_read(env, offsetof(E2KCrs, cr0_lo));
|
||||
case SR_CR1_HI: return cr_read(env, offsetof(E2KCrs, cr1.hi));
|
||||
case SR_CR1_LO: return cr_read(env, offsetof(E2KCrs, cr1.lo));
|
||||
case SR_SCLKM1:
|
||||
case SR_SCLKM2:
|
||||
case SR_CU_HW0: goto todo;
|
||||
case SR_UPSR: return env->upsr;
|
||||
case SR_IP: return env->ip;
|
||||
case SR_NIP: return env->nip;
|
||||
case SR_LSR: return env_lsr_get(env);
|
||||
case SR_PFPFR: return env->pfpfr.raw;
|
||||
case SR_FPCR: return env->fpcr.raw;
|
||||
case SR_FPSR: return env->fpsr.raw;
|
||||
case SR_ILCR: return env_ilcr_get(env);
|
||||
case SR_BR: return env_br_get(env);
|
||||
case SR_BGR: return env->bgr;
|
||||
case SR_IDR: return env->idr;
|
||||
case SR_CLKR: return cpu_get_host_ticks(); // FIXME
|
||||
case SR_RNDPR:
|
||||
case SR_SCLKR:
|
||||
case SR_TIR_HI:
|
||||
case SR_TIR_LO:
|
||||
case SR_RPR:
|
||||
case SR_SBBP:
|
||||
case SR_RPR_HI:
|
||||
case SR_UPSRM: goto todo;
|
||||
case SR_LSR1: return env->lsr_lcnt;
|
||||
case SR_ILCR1: return env->ilcr_lcnt;
|
||||
default:
|
||||
qemu_log_mask(LOG_UNIMP, "read unknown state register 0x%x\n", idx);
|
||||
return 0;
|
||||
/* The index is checked during translation. */
|
||||
g_assert_not_reached();
|
||||
break;
|
||||
}
|
||||
|
||||
todo:
|
||||
qemu_log("reading a state register %#x is not implemented\n", index);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void HELPER(rwd)(CPUE2KState *env, int idx, uint64_t val)
|
||||
{
|
||||
switch(idx) {
|
||||
case 0x80: /* %upsr */
|
||||
env->upsr = val;
|
||||
#define CASE_RWAP_SET(e, f) \
|
||||
case glue(e, _HI): \
|
||||
env->f.hi = value; \
|
||||
break; \
|
||||
case glue(e, _LO): \
|
||||
env->f.lo = value & E2K_RWAP_LO_MASK; \
|
||||
break;
|
||||
case 0x83: /* %lsr */
|
||||
env_lsr_set(env, val);
|
||||
break;
|
||||
case 0x84: /* %pfpfr */
|
||||
env->pfpfr.raw = val;
|
||||
e2k_update_fp_status(env);
|
||||
break;
|
||||
case 0x85: /* %fpcr */
|
||||
env->fpcr.raw = val;
|
||||
e2k_update_fx_status(env);
|
||||
break;
|
||||
case 0x86: env->fpsr.raw = val; break; /* %fpsr */
|
||||
case 0xc3: env->lsr_lcnt = val; break; /* %lsr1 */
|
||||
default:
|
||||
qemu_log_mask(LOG_UNIMP, "rwd unknown state register 0x%x\n", idx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void HELPER(rws)(CPUE2KState *env, int idx, uint32_t val)
|
||||
void HELPER(state_reg_set)(CPUE2KState *env, uint64_t value, int index)
|
||||
{
|
||||
switch (idx) {
|
||||
case 0x80: /* %upsr */
|
||||
env->upsr = deposit64(env->upsr, 0, 32, val);
|
||||
switch (index) {
|
||||
case SR_UPSR:
|
||||
case SR_LSR:
|
||||
case SR_ILCR:
|
||||
case SR_PFPFR:
|
||||
case SR_FPCR:
|
||||
case SR_FPSR:
|
||||
case SR_SCLKR:
|
||||
case SR_TIR_HI:
|
||||
case SR_TIR_LO:
|
||||
case SR_RPR:
|
||||
case SR_SBBP:
|
||||
case SR_RPR_HI:
|
||||
case SR_UPSRM:
|
||||
case SR_LSR1:
|
||||
case SR_ILCR1:
|
||||
break;
|
||||
case 0x83: /* %lsr */
|
||||
env->lsr_lcnt = val;
|
||||
case SR_CUIR:
|
||||
raise_exception(env, EXCP_ILLEGAL_OPCODE); /* FIXME */
|
||||
break;
|
||||
case 0x84: /* %pfpfr */
|
||||
env->pfpfr.raw = val;
|
||||
e2k_update_fp_status(env);
|
||||
break;
|
||||
case 0x85: /* %fpcr */
|
||||
env->fpcr.raw = val;
|
||||
e2k_update_fx_status(env);
|
||||
break;
|
||||
case 0x86: env->fpsr.raw = val; break; /* %fpsr */
|
||||
default:
|
||||
qemu_log_mask(LOG_UNIMP, "rws unknown state register 0x%x\n", idx);
|
||||
if ((env->psr & PSR_PM) == 0) {
|
||||
raise_exception(env, EXCP_PRIV_ACTION);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
switch (index) {
|
||||
case SR_PSR:
|
||||
env->psr = value & PSR_MASK;
|
||||
break;
|
||||
case SR_WD:
|
||||
env_wd_set(env, value);
|
||||
break;
|
||||
case SR_CORE_MODE:
|
||||
// FIXME: core_mode
|
||||
qemu_log("FIXME: core_mode is set to %#lx\n", value);
|
||||
env->core_mode = value;
|
||||
break;
|
||||
case SR_CWD:
|
||||
/* ignore */
|
||||
break;
|
||||
case SR_PSP_HI:
|
||||
env->psp.hi = value;
|
||||
break;
|
||||
case SR_PSP_LO:
|
||||
env->psp.lo = value & E2K_PSP_LO_MASK;
|
||||
break;
|
||||
case SR_PSHTP:
|
||||
/* ignore */
|
||||
break;
|
||||
case SR_PCSP_HI:
|
||||
env->pcsp.hi = value;
|
||||
break;
|
||||
case SR_PCSP_LO:
|
||||
env->pcsp.lo = value & E2K_PSP_LO_MASK;
|
||||
break;
|
||||
case SR_PCSHTP:
|
||||
/* ignore */
|
||||
break;
|
||||
case SR_CTPR1:
|
||||
env->ctprs[0].raw = value;
|
||||
break;
|
||||
case SR_CTPR2:
|
||||
env->ctprs[1].raw = value;
|
||||
break;
|
||||
case SR_CTPR3:
|
||||
env->ctprs[2].raw = value;
|
||||
break;
|
||||
case SR_SBR:
|
||||
env->sbr = value;
|
||||
break;
|
||||
case SR_CUTD:
|
||||
case SR_EIR:
|
||||
case SR_TSD:
|
||||
goto todo;
|
||||
case SR_CUIR:
|
||||
env->cuir = value & CUIR_MASK;
|
||||
break;
|
||||
case SR_OSEM:
|
||||
case SR_TR:
|
||||
goto todo;
|
||||
case SR_OSR0:
|
||||
env->osr0 = value;
|
||||
break;
|
||||
CASE_RWAP_SET(SR_OSCUD, oscud)
|
||||
CASE_RWAP_SET(SR_OSGD, osgd)
|
||||
CASE_RWAP_SET(SR_USD, usd)
|
||||
CASE_RWAP_SET(SR_CUD, cud)
|
||||
CASE_RWAP_SET(SR_GD, gd)
|
||||
CASE_RWAP_SET(SR_CS, cs)
|
||||
CASE_RWAP_SET(SR_DS, ds)
|
||||
CASE_RWAP_SET(SR_ES, es)
|
||||
CASE_RWAP_SET(SR_FS, fs)
|
||||
CASE_RWAP_SET(SR_GS, gs)
|
||||
CASE_RWAP_SET(SR_SS, ss)
|
||||
case SR_DIBCR:
|
||||
case SR_DIMCR:
|
||||
case SR_DIBSR:
|
||||
case SR_DTCR:
|
||||
case SR_DIBAR0:
|
||||
case SR_DIBAR1:
|
||||
case SR_DIBAR2:
|
||||
case SR_DIBAR3:
|
||||
case SR_DIMAR0:
|
||||
case SR_DIMAR1:
|
||||
case SR_DTRAF:
|
||||
case SR_DTART:
|
||||
case SR_CR0_HI:
|
||||
case SR_CR0_LO:
|
||||
case SR_CR1_HI:
|
||||
case SR_CR1_LO:
|
||||
case SR_SCLKM1:
|
||||
case SR_SCLKM2:
|
||||
case SR_CU_HW0:
|
||||
goto todo;
|
||||
case SR_UPSR:
|
||||
env->upsr = value & UPSR_MASK;
|
||||
break;
|
||||
case SR_LSR:
|
||||
env_lsr_set(env, value);
|
||||
env_ilcr_set(env, value);
|
||||
break;
|
||||
case SR_PFPFR:
|
||||
env->pfpfr.raw = value;
|
||||
e2k_update_fp_status(env);
|
||||
break;
|
||||
case SR_FPCR:
|
||||
env->fpcr.raw = value;
|
||||
e2k_update_fx_status(env);
|
||||
break;
|
||||
case SR_FPSR:
|
||||
env->fpsr.raw = value;
|
||||
break;
|
||||
case SR_ILCR:
|
||||
env->ilcr = (value >> LSR_ECNT_OFF) & ILCR_MASK;
|
||||
env->ilcr_lcnt = value & GEN_MASK(0, LSR_LCNT_LEN);
|
||||
break;
|
||||
case SR_BR:
|
||||
env_br_set(env, value);
|
||||
break;
|
||||
case SR_BGR:
|
||||
env->bgr = value & BGR_MASK;
|
||||
break;
|
||||
case SR_RNDPR:
|
||||
case SR_SCLKR:
|
||||
case SR_TIR_HI:
|
||||
case SR_TIR_LO:
|
||||
case SR_RPR:
|
||||
case SR_SBBP:
|
||||
case SR_RPR_HI:
|
||||
case SR_UPSRM:
|
||||
goto todo;
|
||||
case SR_LSR1:
|
||||
env->lsr_lcnt = value;
|
||||
env->ilcr_lcnt = value;
|
||||
break;
|
||||
case SR_ILCR1:
|
||||
env->ilcr_lcnt = value;
|
||||
break;
|
||||
default:
|
||||
/* The index is checked during translation. */
|
||||
g_assert_not_reached();
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
todo:
|
||||
qemu_log("write to state register %#x is not implemented\n", index);
|
||||
}
|
||||
|
||||
uint64_t HELPER(getsp)(CPUE2KState *env, uint32_t src2)
|
||||
|
|
|
@ -3505,9 +3505,8 @@ static void gen_rrd(Alop *alop)
|
|||
Tagged_i64 r = tagged_new_i64();
|
||||
TCGv_i32 t0 = tcg_const_i32(alop->als.src1);
|
||||
|
||||
// TODO: check version
|
||||
gen_save_cpu_state(alop->ctx);
|
||||
gen_helper_rrd(r.val, cpu_env, t0);
|
||||
gen_helper_state_reg_get(r.val, cpu_env, t0);
|
||||
tcg_gen_movi_i32(r.tag, 0);
|
||||
gen_al_result_d(alop, r);
|
||||
|
||||
|
@ -3515,22 +3514,36 @@ static void gen_rrd(Alop *alop)
|
|||
tagged_free_i64(r);
|
||||
}
|
||||
|
||||
#define IMPL_GEN_RW(name, S, helper) \
|
||||
static void name(Alop *alop) \
|
||||
{ \
|
||||
tagged(S) b = tagged_new(S); \
|
||||
TCGv_i32 t0 = tcg_const_i32(alop->als.dst); \
|
||||
\
|
||||
/* TODO: check version */ \
|
||||
gen_tagged_src(2, S, alop, b); \
|
||||
helper(cpu_env, t0, b.val); \
|
||||
\
|
||||
tcg_temp_free_i32(t0); \
|
||||
tagged_free(S, b); \
|
||||
}
|
||||
static inline void gen_state_reg_write(Alop *alop, TCGv_i64 value)
|
||||
{
|
||||
TCGv_i32 t0 = tcg_const_i32(alop->als.dst);
|
||||
|
||||
IMPL_GEN_RW(gen_rwd, d, gen_helper_rwd)
|
||||
IMPL_GEN_RW(gen_rws, s, gen_helper_rws)
|
||||
gen_helper_state_reg_set(cpu_env, value, t0);
|
||||
tcg_temp_free_i32(t0);
|
||||
}
|
||||
|
||||
static void gen_rws(Alop *alop)
|
||||
{
|
||||
Tagged_i32 s2 = tagged_new_i32();
|
||||
TCGv_i64 t0 = tcg_temp_new_i64();
|
||||
|
||||
gen_tagged_src2_s(alop, s2);
|
||||
gen_delayed_alop_tag_check(alop, s2.tag);
|
||||
tcg_gen_extu_i32_i64(t0, s2.val);
|
||||
gen_state_reg_write(alop, t0);
|
||||
tcg_temp_free_i64(t0);
|
||||
tagged_free_i32(s2);
|
||||
}
|
||||
|
||||
static void gen_rwd(Alop *alop)
|
||||
{
|
||||
Tagged_i64 s2 = tagged_new_i64();
|
||||
|
||||
gen_tagged_src2_d(alop, s2);
|
||||
gen_delayed_alop_tag_check(alop, s2.tag);
|
||||
gen_state_reg_write(alop, s2.val);
|
||||
tagged_free_i64(s2);
|
||||
}
|
||||
|
||||
#define IMPL_GEN_MOV(name, S, code) \
|
||||
static void name(Alop *alop) \
|
||||
|
@ -7660,7 +7673,7 @@ static void gen_stubs(DisasContext *ctx)
|
|||
}
|
||||
}
|
||||
|
||||
static inline target_ulong do_decode(DisasContext *ctx, CPUState *cs)
|
||||
static target_ulong do_decode(DisasContext *ctx, CPUState *cs)
|
||||
{
|
||||
E2KCPU *cpu = E2K_CPU(cs);
|
||||
CPUE2KState *env = &cpu->env;
|
||||
|
@ -7682,6 +7695,127 @@ static inline target_ulong do_decode(DisasContext *ctx, CPUState *cs)
|
|||
return ctx->pc + len;
|
||||
}
|
||||
|
||||
static bool validate_state_reg(DisasContext *ctx, int index, bool write)
|
||||
{
|
||||
switch (index) {
|
||||
case SR_PSR:
|
||||
case SR_WD:
|
||||
case SR_CWD:
|
||||
case SR_PSP_HI:
|
||||
case SR_PSP_LO:
|
||||
case SR_PSHTP:
|
||||
case SR_PCSP_HI:
|
||||
case SR_PCSP_LO:
|
||||
case SR_PCSHTP:
|
||||
case SR_CTPR1:
|
||||
case SR_CTPR2:
|
||||
case SR_CTPR3:
|
||||
case SR_SBR:
|
||||
case SR_CUTD:
|
||||
case SR_CUIR:
|
||||
case SR_OSCUD_HI:
|
||||
case SR_OSCUD_LO:
|
||||
case SR_OSGD_HI:
|
||||
case SR_OSGD_LO:
|
||||
case SR_OSEM:
|
||||
case SR_USD_HI:
|
||||
case SR_USD_LO:
|
||||
case SR_OSR0:
|
||||
case SR_CUD_HI:
|
||||
case SR_CUD_LO:
|
||||
case SR_GD_HI:
|
||||
case SR_GD_LO:
|
||||
case SR_CS_HI:
|
||||
case SR_CS_LO:
|
||||
case SR_DS_HI:
|
||||
case SR_DS_LO:
|
||||
case SR_ES_HI:
|
||||
case SR_ES_LO:
|
||||
case SR_FS_HI:
|
||||
case SR_FS_LO:
|
||||
case SR_GS_HI:
|
||||
case SR_GS_LO:
|
||||
case SR_SS_HI:
|
||||
case SR_SS_LO:
|
||||
case SR_DIBCR:
|
||||
case SR_DIMCR:
|
||||
case SR_DIBSR:
|
||||
case SR_DTCR:
|
||||
case SR_DIBAR0:
|
||||
case SR_DIBAR1:
|
||||
case SR_DIBAR2:
|
||||
case SR_DIBAR3:
|
||||
case SR_DIMAR0:
|
||||
case SR_DIMAR1:
|
||||
case SR_DTRAF:
|
||||
case SR_DTART:
|
||||
case SR_CR0_HI:
|
||||
case SR_CR0_LO:
|
||||
case SR_CR1_HI:
|
||||
case SR_CR1_LO:
|
||||
case SR_SCLKM1:
|
||||
case SR_SCLKM2:
|
||||
case SR_CU_HW0:
|
||||
case SR_UPSR:
|
||||
case SR_NIP:
|
||||
case SR_LSR:
|
||||
case SR_PFPFR:
|
||||
case SR_FPCR:
|
||||
case SR_FPSR:
|
||||
case SR_ILCR:
|
||||
case SR_BR:
|
||||
case SR_BGR:
|
||||
case SR_CLKR:
|
||||
case SR_RNDPR:
|
||||
case SR_SCLKR:
|
||||
case SR_TIR_HI:
|
||||
case SR_TIR_LO:
|
||||
case SR_RPR:
|
||||
case SR_SBBP:
|
||||
case SR_RPR_HI:
|
||||
case SR_UPSRM:
|
||||
return true;
|
||||
case SR_IDR:
|
||||
case SR_IP:
|
||||
return !write;
|
||||
case SR_EIR:
|
||||
case SR_TSD:
|
||||
case SR_TR:
|
||||
return false; /* FIXME */
|
||||
case SR_CORE_MODE:
|
||||
return ctx->version >= 3;
|
||||
case SR_LSR1:
|
||||
case SR_ILCR1:
|
||||
return ctx->version >= 5;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static void validate_bundle(DisasContext *ctx)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
Alop *alop = &ctx->alops[i];
|
||||
|
||||
switch (alop->format) {
|
||||
case ALOPF15:
|
||||
if (!validate_state_reg(ctx, alop->als.dst, true)) {
|
||||
gen_tr_excp_illopc(alop->ctx);
|
||||
}
|
||||
break;
|
||||
case ALOPF16:
|
||||
if (!validate_state_reg(ctx, alop->als.src2, false)) {
|
||||
gen_tr_excp_illopc(alop->ctx);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void gen_window_bounds_checki_i32(TCGCond cond, TCGv_i32 arg1,
|
||||
int arg2)
|
||||
{
|
||||
|
@ -7964,6 +8098,7 @@ static void e2k_tr_translate_insn(DisasContextBase *db, CPUState *cs)
|
|||
#endif /* CONFIG_USER_ONLY */
|
||||
|
||||
ctx->loop_mode = (ctx->bundle.hs & (1 << 10)) != 0;
|
||||
validate_bundle(ctx);
|
||||
gen_alop_reg_indices_check(ctx);
|
||||
gen_setwd(ctx);
|
||||
gen_cs0(ctx);
|
||||
|
|
Loading…
Reference in New Issue