e2k: Impl e2k_longjmp2 syscall.
This commit is contained in:
parent
db26409a33
commit
06df1e9168
|
@ -25,6 +25,8 @@
|
|||
#include "user-mmap.h"
|
||||
#include "cpu_loop-common.h"
|
||||
|
||||
void helper_return(CPUE2KState *env);
|
||||
|
||||
void cpu_loop(CPUE2KState *env)
|
||||
{
|
||||
CPUState *cs = env_cpu(env);
|
||||
|
@ -39,34 +41,32 @@ void cpu_loop(CPUE2KState *env)
|
|||
|
||||
switch (trapnr) {
|
||||
case E2K_EXCP_SYSCALL: {
|
||||
int offset = E2K_NR_COUNT + env->wd.base + env->syscall_wbs * 2;
|
||||
uint64_t *regs = env->regs;
|
||||
abi_ulong ret = do_syscall(env,
|
||||
regs[(0 + offset) % E2K_NR_COUNT],
|
||||
regs[(1 + offset) % E2K_NR_COUNT],
|
||||
regs[(2 + offset) % E2K_NR_COUNT],
|
||||
regs[(3 + offset) % E2K_NR_COUNT],
|
||||
regs[(4 + offset) % E2K_NR_COUNT],
|
||||
regs[(5 + offset) % E2K_NR_COUNT],
|
||||
regs[(6 + offset) % E2K_NR_COUNT],
|
||||
regs[(7 + offset) % E2K_NR_COUNT],
|
||||
regs[(8 + offset) % E2K_NR_COUNT]
|
||||
);
|
||||
abi_long args[10] = { 0 };
|
||||
int psize = env->wd.psize <= 10 ? env->wd.psize : 10;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < psize; i++) {
|
||||
args[i] = env->regs[e2k_wrap_reg_index(env->wd.base + i)];
|
||||
}
|
||||
|
||||
abi_ulong ret = do_syscall(env, args[0], args[1], args[2], args[3],
|
||||
args[4], args[5], args[6], args[7], args[8]);
|
||||
|
||||
if (ret == -TARGET_ERESTARTSYS) {
|
||||
/* TODO: restart syscall */
|
||||
abort();
|
||||
} else if (ret != -TARGET_QEMU_ESIGRETURN) {
|
||||
unsigned int i;
|
||||
} else if (env->wd.psize > 0 && ret != -TARGET_QEMU_ESIGRETURN) {
|
||||
env->regs[env->wd.base] = ret;
|
||||
env->tags[env->wd.base] = 0;
|
||||
|
||||
env->regs[offset % E2K_NR_COUNT] = ret;
|
||||
env->tags[offset % E2K_NR_COUNT] = 0;
|
||||
|
||||
for (i = 1; i < 8; i++) {
|
||||
int idx = (offset + i) % E2K_NR_COUNT;
|
||||
env->regs[idx] = 0;
|
||||
env->tags[idx] = E2K_TAG_NON_NUMBER64;
|
||||
for (i = 1; i < env->wd.psize; i++) {
|
||||
int index = e2k_wrap_reg_index(env->wd.base + i);
|
||||
env->regs[index] = 0;
|
||||
env->tags[index] = E2K_TAG_NON_NUMBER64;
|
||||
}
|
||||
}
|
||||
// FIXME: Can call helpers from here?
|
||||
helper_return(env);
|
||||
break;
|
||||
}
|
||||
case E2K_EXCP_ILLOPC:
|
||||
|
@ -129,4 +129,7 @@ void target_cpu_copy_regs(CPUE2KState *env, struct target_pt_regs *regs)
|
|||
env->sbr = regs->sbr;
|
||||
|
||||
e2k_break_save_state(env);
|
||||
|
||||
env->pcs_base = env->pcsp.base;
|
||||
env->ps_base = env->psp.base;
|
||||
}
|
||||
|
|
|
@ -25,4 +25,17 @@ struct target_shmid_ds {
|
|||
void *shm_unused3;
|
||||
};
|
||||
|
||||
struct target_jmp_info {
|
||||
abi_ullong sigmask;
|
||||
abi_ullong cr0hi;
|
||||
abi_ullong cr1lo;
|
||||
abi_ullong pcsplo;
|
||||
abi_ullong pcsphi;
|
||||
abi_uint pcshtp;
|
||||
abi_uint br;
|
||||
abi_ullong usdlo;
|
||||
abi_ullong wd;
|
||||
abi_ullong reserv1;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -62,5 +62,12 @@ struct target_pt_regs {
|
|||
uint16_t gext[32];
|
||||
};
|
||||
|
||||
// FIXME: Is it right place for these constants?
|
||||
#if TARGET_LONG_BITS == 64
|
||||
#define TARGET_PAGE_OFFSET 0x0000d00000000000UL
|
||||
#define TARGET_TASK_SIZE TARGET_PAGE_OFFSET
|
||||
#else
|
||||
#define TARGET_TASK_SIZE 0xf0000000UL
|
||||
#endif
|
||||
|
||||
#endif /* E2K_TARGET_SYSCALL_H */
|
||||
|
|
|
@ -3761,6 +3761,19 @@ print_ioctl(CPUArchState *cpu_env, const struct syscallname *name,
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_NR_e2k_longjmp2
|
||||
static void
|
||||
print_e2k_jmp_info(void *cpu_env, const struct syscallname *name,
|
||||
abi_long arg0, abi_long arg1, abi_long arg2,
|
||||
abi_long arg3, abi_long arg4, abi_long arg5)
|
||||
{
|
||||
print_syscall_prologue(name);
|
||||
print_pointer(arg0, 0);
|
||||
print_raw_param("%d", arg1, 1);
|
||||
print_syscall_epilogue(name);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* An array of all of the syscalls we know about
|
||||
*/
|
||||
|
|
|
@ -126,6 +126,10 @@
|
|||
#ifdef TARGET_NR_dup3
|
||||
{ TARGET_NR_dup3, "dup3" , "%s(%d,%d,%d)", NULL, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_e2k_longjmp2
|
||||
{ TARGET_NR_e2k_longjmp2, "e2k_longjmp2", "%s(%p, %d)",
|
||||
print_e2k_jmp_info, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_epoll_create
|
||||
{ TARGET_NR_epoll_create, "epoll_create", "%s(%d)", NULL, NULL },
|
||||
#endif
|
||||
|
|
|
@ -6987,6 +6987,86 @@ static inline abi_long copy_to_user_flock64(abi_ulong target_flock_addr,
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef TARGET_E2K
|
||||
static inline abi_long copy_from_user_jmp_info(struct target_jmp_info *ji,
|
||||
abi_ulong target_jmp_info_addr)
|
||||
{
|
||||
struct target_jmp_info *target_ji;
|
||||
|
||||
if (!lock_user_struct(VERIFY_READ, target_ji, target_jmp_info_addr, 1)) {
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
__get_user(ji->sigmask, &target_ji->sigmask);
|
||||
__get_user(ji->cr0hi, &target_ji->cr0hi);
|
||||
__get_user(ji->cr1lo, &target_ji->cr1lo);
|
||||
__get_user(ji->pcsplo, &target_ji->pcsplo);
|
||||
__get_user(ji->pcsphi, &target_ji->pcsphi);
|
||||
__get_user(ji->pcshtp, &target_ji->pcshtp);
|
||||
__get_user(ji->br, &target_ji->br);
|
||||
__get_user(ji->usdlo, &target_ji->usdlo);
|
||||
__get_user(ji->wd, &target_ji->wd);
|
||||
__get_user(ji->reserv1, &target_ji->reserv1);
|
||||
unlock_user_struct(target_ji, target_jmp_info_addr, 0);
|
||||
if (ji->cr0hi > TARGET_TASK_SIZE) {
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline abi_long copy_from_user_crs(E2KCrs *crs,
|
||||
abi_ulong target_crs_addr)
|
||||
{
|
||||
E2KCrs *target_crs;
|
||||
|
||||
if (!lock_user_struct(VERIFY_READ, target_crs, target_crs_addr, 1)) {
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
__get_user(crs->cr0_lo, &target_crs->cr0_lo);
|
||||
__get_user(crs->cr0_hi, &target_crs->cr0_hi);
|
||||
__get_user(crs->cr1.lo, &target_crs->cr1.lo);
|
||||
__get_user(crs->cr1.hi, &target_crs->cr1.hi);
|
||||
unlock_user_struct(target_crs, target_crs_addr, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static abi_long do_e2k_longjmp2(CPUE2KState *env, struct target_jmp_info *jmp_info)
|
||||
{
|
||||
E2KPcsState jmp_pcsp;
|
||||
E2KCrs crs = env->crs;
|
||||
int level; /* how many CRs need to restore */
|
||||
int pcs_index = env->pcsp.index;
|
||||
int ps_index = env->psp.index;
|
||||
int psize = env->wd.psize;
|
||||
int ret, i;
|
||||
|
||||
jmp_pcsp.lo = jmp_info->pcsplo;
|
||||
jmp_pcsp.hi = jmp_info->pcsphi;
|
||||
|
||||
level = (env->pcsp.index - jmp_pcsp.index) / CRS_SIZE;
|
||||
for (i = 0; i < level; i++) {
|
||||
// FIXME: nfx
|
||||
psize = crs.cr1.wpsz * 2;
|
||||
ps_index -= crs.cr1.wbs * E2K_REG_LEN * 4;
|
||||
pcs_index -= CRS_SIZE;
|
||||
ret = copy_from_user_crs(&crs, env->pcsp.base + pcs_index);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
env->crs.cr0_hi = jmp_info->cr0hi;
|
||||
env->crs.cr1.lo = jmp_info->cr1lo;
|
||||
env->crs.cr1.br = jmp_info->br;
|
||||
env->crs.cr1.ussz = (env->sbr - extract64(jmp_info->usdlo, 0, 48)) >> 4;
|
||||
env->pcsp.index = pcs_index;
|
||||
env->psp.index = ps_index;
|
||||
env->wd.base = 0;
|
||||
env->wd.psize = psize;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* end of TARGET_E2K */
|
||||
|
||||
static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
|
||||
{
|
||||
struct flock64 fl64;
|
||||
|
@ -11885,6 +11965,19 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
|
|||
#endif
|
||||
return ret;
|
||||
#endif
|
||||
#ifdef TARGET_NR_e2k_longjmp2
|
||||
case TARGET_NR_e2k_longjmp2: {
|
||||
E2KCPU *e2k_cpu = E2K_CPU(cpu);
|
||||
CPUE2KState *env = &e2k_cpu->env;
|
||||
struct target_jmp_info ji;
|
||||
ret = copy_from_user_jmp_info(&ji, arg1);
|
||||
if (ret) {
|
||||
break;
|
||||
}
|
||||
do_e2k_longjmp2(env, &ji);
|
||||
return arg2;
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_ATTR
|
||||
#ifdef TARGET_NR_setxattr
|
||||
case TARGET_NR_listxattr:
|
||||
|
|
|
@ -44,8 +44,8 @@ static void e2k_cpu_reset(DeviceState *dev)
|
|||
|
||||
memset(env, 0, offsetof(CPUE2KState, end_reset_fields));
|
||||
|
||||
env->cr1.wpsz = 4;
|
||||
env->cr1.wbs = 4;
|
||||
env->crs.cr1.wpsz = 4;
|
||||
env->crs.cr1.wbs = 4;
|
||||
env->wd.base = 0;
|
||||
env->wd.size = 16;
|
||||
env->wd.psize = 8;
|
||||
|
@ -61,7 +61,7 @@ static void e2k_cpu_reset(DeviceState *dev)
|
|||
e2k_update_fp_status(env);
|
||||
|
||||
// FIXME: testing
|
||||
env->idr = 0x3a207; // mimic 8c
|
||||
env->idr = 0x3a207; /* mimic 8c */
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SOFTMMU
|
||||
|
@ -157,10 +157,10 @@ void e2k_cpu_dump_state(CPUState *cs, FILE *f, int flags)
|
|||
|
||||
qemu_fprintf(f, " ip = 0x%016lx\n", env->ip);
|
||||
qemu_fprintf(f, " pregs = 0x%016lx\n", env->pregs);
|
||||
qemu_fprintf(f, " cr0_lo = 0x%016lx\n", env->cr0_lo);
|
||||
qemu_fprintf(f, " cr0_hi = 0x%016lx\n", env->cr0_hi);
|
||||
qemu_fprintf(f, " cr1_lo = 0x%016lx\n", env->cr1.lo);
|
||||
qemu_fprintf(f, " cr1_hi = 0x%016lx\n", env->cr1.hi);
|
||||
qemu_fprintf(f, " cr0_lo = 0x%016lx\n", env->crs.cr0_lo);
|
||||
qemu_fprintf(f, " cr0_hi = 0x%016lx\n", env->crs.cr0_hi);
|
||||
qemu_fprintf(f, " cr1_lo = 0x%016lx\n", env->crs.cr1.lo);
|
||||
qemu_fprintf(f, " cr1_hi = 0x%016lx\n", env->crs.cr1.hi);
|
||||
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));
|
||||
|
|
|
@ -41,6 +41,8 @@ typedef enum {
|
|||
E2K_TAG_NON_NUMBER64 = 5,
|
||||
} E2kRegisterTag;
|
||||
|
||||
#define CRS_SIZE (sizeof(E2KCrs))
|
||||
|
||||
#define CTPR_BASE_OFF 0
|
||||
#define CTPR_BASE_END 47
|
||||
#define CTPR_BASE_LEN (CTPR_BASE_END - CTPR_BASE_OFF + 1)
|
||||
|
@ -313,15 +315,36 @@ typedef struct {
|
|||
};
|
||||
uint64_t hi;
|
||||
};
|
||||
} E2KCr1State;
|
||||
} E2KCr1;
|
||||
|
||||
typedef struct {
|
||||
target_ulong base;
|
||||
uint64_t cr0_lo;
|
||||
uint64_t cr0_hi;
|
||||
E2KCr1 cr1;
|
||||
} E2KCrs;
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
struct {
|
||||
uint64_t base: 48; /* 47:0 */
|
||||
uint64_t unused1: 7; /* 55:48 */
|
||||
uint64_t stub3: 1; /* 56 */
|
||||
uint64_t stub2: 1; /* 57 */
|
||||
uint64_t stub1: 1; /* 58 */
|
||||
uint64_t is_readable: 1; /* 59 */
|
||||
uint64_t is_writable: 1; /* 60 */
|
||||
uint64_t itag: 3; /* 63:61 */
|
||||
};
|
||||
uint64_t lo;
|
||||
};
|
||||
union {
|
||||
struct {
|
||||
uint64_t index: 32; /* 31:0 */
|
||||
uint64_t size: 32; /* 63:32 */
|
||||
};
|
||||
uint64_t hi;
|
||||
};
|
||||
target_ulong base_tag;
|
||||
uint32_t index;
|
||||
uint32_t size;
|
||||
bool is_readable;
|
||||
bool is_writable;
|
||||
} E2KStackState, E2KPsState, E2KPcsState;
|
||||
|
||||
typedef struct {
|
||||
|
@ -594,9 +617,7 @@ typedef struct CPUArchState {
|
|||
E2KDamEntry dam[32];
|
||||
|
||||
/* procedure chain info */
|
||||
uint64_t cr0_lo;
|
||||
uint64_t cr0_hi;
|
||||
E2KCr1State cr1;
|
||||
E2KCrs crs;
|
||||
|
||||
/* Procedure chain info = cr0_lo, cr0_hi, cr1_lo, cr1_hi */
|
||||
E2KPcsState pcsp;
|
||||
|
@ -640,6 +661,9 @@ typedef struct CPUArchState {
|
|||
/* zeroing upper register half for 32-bit instructions */
|
||||
uint32_t wdbl;
|
||||
|
||||
target_ulong pcs_base;
|
||||
target_ulong ps_base;
|
||||
|
||||
/* Fields up to this point are cleared by a CPU reset */
|
||||
struct {} end_reset_fields;
|
||||
|
||||
|
@ -749,6 +773,14 @@ static inline uint64_t e2k_state_wd(CPUE2KState *env)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static inline void e2k_state_wd_set(CPUE2KState *env, uint64_t raw)
|
||||
{
|
||||
env->wd.base = extract64(raw, WD_BASE_OFF, WD_BASE_LEN) / 8;
|
||||
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;
|
||||
|
|
|
@ -62,8 +62,8 @@ int e2k_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
|
|||
case 51: return gdb_get_reg64(mem_buf, e2k_state_pshtp(env)); // pshtp
|
||||
case 52: return gdb_get_reg64(mem_buf, env->pregs); // pregs
|
||||
case 53: return gdb_get_reg64(mem_buf, env->ip); // ip
|
||||
case 54: return gdb_get_reg64(mem_buf, env->cr1.lo); // cr1_lo
|
||||
case 55: return gdb_get_reg64(mem_buf, env->cr1.hi); // cr1_hi
|
||||
case 54: return gdb_get_reg64(mem_buf, env->crs.cr1.lo); // cr1_lo
|
||||
case 55: return gdb_get_reg64(mem_buf, env->crs.cr1.hi); // 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
|
||||
|
|
|
@ -59,21 +59,21 @@ static inline uint64_t ps_pop(CPUE2KState *env, uint8_t *ret_tag)
|
|||
|
||||
static void proc_chain_save(CPUE2KState *env, int wbs)
|
||||
{
|
||||
pcs_push(env, env->cr0_lo);
|
||||
pcs_push(env, env->cr0_hi);
|
||||
pcs_push(env, env->cr1.lo);
|
||||
pcs_push(env, env->cr1.hi);
|
||||
pcs_push(env, env->crs.cr0_lo);
|
||||
pcs_push(env, env->crs.cr0_hi);
|
||||
pcs_push(env, env->crs.cr1.lo);
|
||||
pcs_push(env, env->crs.cr1.hi);
|
||||
|
||||
env->pshtp.index += wbs * 2;
|
||||
|
||||
env->cr0_lo = env->pregs;
|
||||
env->cr0_hi = env->ip;
|
||||
env->cr1.wbs = wbs;
|
||||
env->cr1.wpsz = env->wd.psize / 2;
|
||||
env->cr1.wfx = env->wd.fx;
|
||||
env->cr1.wdbl = env->wdbl;
|
||||
env->cr1.br = e2k_state_br(env);
|
||||
env->cr1.ussz = env->usd.size >> 4;
|
||||
env->crs.cr0_lo = env->pregs;
|
||||
env->crs.cr0_hi = env->ip;
|
||||
env->crs.cr1.wbs = wbs;
|
||||
env->crs.cr1.wpsz = env->wd.psize / 2;
|
||||
env->crs.cr1.wfx = env->wd.fx;
|
||||
env->crs.cr1.wdbl = env->wdbl;
|
||||
env->crs.cr1.br = e2k_state_br(env);
|
||||
env->crs.cr1.ussz = env->usd.size >> 4;
|
||||
|
||||
env->wd.fx = true;
|
||||
env->wd.base = e2k_wrap_reg_index(env->wd.base + wbs * 2);
|
||||
|
@ -85,47 +85,64 @@ static inline void proc_chain_restore(CPUE2KState *env)
|
|||
{
|
||||
int wbs;
|
||||
|
||||
env->pregs = env->cr0_lo;
|
||||
env->ip = env->cr0_hi;
|
||||
wbs = env->cr1.wbs;
|
||||
e2k_state_br_set(env, env->cr1.br);
|
||||
env->pregs = env->crs.cr0_lo;
|
||||
env->ip = env->crs.cr0_hi;
|
||||
wbs = env->crs.cr1.wbs;
|
||||
e2k_state_br_set(env, env->crs.cr1.br);
|
||||
env->wd.size = env->wd.psize + wbs * 2;
|
||||
env->wd.psize = env->cr1.wpsz * 2;
|
||||
env->wd.psize = env->crs.cr1.wpsz * 2;
|
||||
env->wd.base = e2k_wrap_reg_index(env->wd.base - wbs * 2);
|
||||
env->wd.fx = env->cr1.wfx;
|
||||
env->wdbl = env->cr1.wdbl;
|
||||
env->usd.size = env->cr1.ussz << 4;
|
||||
env->wd.fx = env->crs.cr1.wfx;
|
||||
env->wdbl = env->crs.cr1.wdbl;
|
||||
env->usd.size = env->crs.cr1.ussz << 4;
|
||||
env->usd.base = env->sbr - env->usd.size;
|
||||
|
||||
env->pshtp.index -= wbs * 2;
|
||||
|
||||
env->cr1.hi = pcs_pop(env);
|
||||
env->cr1.lo = pcs_pop(env);
|
||||
env->cr0_hi = pcs_pop(env);
|
||||
env->cr0_lo = pcs_pop(env);
|
||||
env->crs.cr1.hi = pcs_pop(env);
|
||||
env->crs.cr1.lo = pcs_pop(env);
|
||||
env->crs.cr0_hi = pcs_pop(env);
|
||||
env->crs.cr0_lo = pcs_pop(env);
|
||||
}
|
||||
|
||||
static inline void ps_spill(CPUE2KState *env, bool force, bool force_fx)
|
||||
static inline void ps_spill_round(CPUE2KState *env, bool force_fx)
|
||||
{
|
||||
while (E2K_NR_COUNT < env->pshtp.index + env->wd.size ||
|
||||
(force && env->wd.size + env->pshtp.index))
|
||||
{
|
||||
int i = e2k_wrap_reg_index(env->wd.base - env->pshtp.index);
|
||||
ps_push(env, env->regs[i], env->tags[i]);
|
||||
ps_push(env, env->regs[i + 1], env->tags[i + 1]);
|
||||
int i = e2k_wrap_reg_index(env->wd.base - env->pshtp.index);
|
||||
ps_push(env, env->regs[i], env->tags[i]);
|
||||
ps_push(env, env->regs[i + 1], env->tags[i + 1]);
|
||||
|
||||
// TODO: push fx
|
||||
if (force_fx) {
|
||||
ps_push(env, env->xregs[i], 0);
|
||||
ps_push(env, env->xregs[i + 1], 0);
|
||||
}
|
||||
// TODO: push fx
|
||||
if (force_fx) {
|
||||
ps_push(env, env->xregs[i], 0);
|
||||
ps_push(env, env->xregs[i + 1], 0);
|
||||
}
|
||||
|
||||
env->regs[i] = 0;
|
||||
env->tags[i] = E2K_TAG_NON_NUMBER64;
|
||||
env->regs[i + 1] = 0;
|
||||
env->tags[i + 1] = E2K_TAG_NON_NUMBER64;
|
||||
env->regs[i] = 0;
|
||||
env->tags[i] = E2K_TAG_NON_NUMBER64;
|
||||
env->regs[i + 1] = 0;
|
||||
env->tags[i + 1] = E2K_TAG_NON_NUMBER64;
|
||||
|
||||
env->pshtp.index -= 2;
|
||||
env->pshtp.index -= 2;
|
||||
}
|
||||
|
||||
static inline void ps_spill_all(CPUE2KState *env, bool force_fx)
|
||||
{
|
||||
while (env->pshtp.index > 0) {
|
||||
ps_spill_round(env, force_fx);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void ps_spill_debug(CPUE2KState *env, bool force_fx)
|
||||
{
|
||||
while (env->wd.size + env->pshtp.index) {
|
||||
ps_spill_round(env, force_fx);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void ps_spill(CPUE2KState *env, bool force_fx)
|
||||
{
|
||||
while (E2K_NR_COUNT < env->pshtp.index + env->wd.size) {
|
||||
ps_spill_round(env, force_fx);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -167,7 +184,7 @@ void helper_setwd(CPUE2KState *env, uint32_t lts)
|
|||
env->wdbl = dbl;
|
||||
}
|
||||
|
||||
ps_spill(env, false, PS_FORCE_FX);
|
||||
ps_spill(env, PS_FORCE_FX);
|
||||
|
||||
if (old_size < size) {
|
||||
unsigned int i, offset = env->wd.base + old_size;
|
||||
|
@ -189,7 +206,7 @@ uint64_t helper_prep_return(CPUE2KState *env, int ipd)
|
|||
return 0;
|
||||
}
|
||||
|
||||
ret.base = env->cr0_hi;
|
||||
ret.base = env->crs.cr0_hi;
|
||||
ret.tag = CTPR_TAG_RETURN;
|
||||
ret.ipd = ipd;
|
||||
|
||||
|
@ -207,11 +224,10 @@ static inline void do_syscall(CPUE2KState *env, int call_wbs,
|
|||
target_ulong pc_next)
|
||||
{
|
||||
CPUState *cs = env_cpu(env);
|
||||
|
||||
env->ip = pc_next;
|
||||
env->syscall_wbs = call_wbs;
|
||||
proc_chain_save(env, call_wbs);
|
||||
ps_spill_all(env, PS_FORCE_FX);
|
||||
reset_ctprs(env);
|
||||
|
||||
cs->exception_index = E2K_EXCP_SYSCALL;
|
||||
cpu_loop_exit(cs);
|
||||
}
|
||||
|
@ -241,7 +257,7 @@ void helper_raise_exception(CPUE2KState *env, int tt)
|
|||
cs->exception_index = tt;
|
||||
|
||||
proc_chain_save(env, env->wd.size / 2);
|
||||
ps_spill(env, true, true);
|
||||
ps_spill_debug(env, PS_FORCE_FX);
|
||||
|
||||
cpu_loop_exit(cs);
|
||||
}
|
||||
|
@ -257,7 +273,7 @@ void e2k_break_save_state(CPUE2KState *env)
|
|||
{
|
||||
env->is_bp = true;
|
||||
proc_chain_save(env, env->wd.size / 2);
|
||||
ps_spill(env, true, true);
|
||||
ps_spill(env, PS_FORCE_FX);
|
||||
}
|
||||
|
||||
void helper_break_restore_state(CPUE2KState *env)
|
||||
|
@ -274,7 +290,7 @@ bool e2k_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
|
|||
CPUE2KState *env = &cpu->env;
|
||||
|
||||
proc_chain_save(env, env->wd.size / 2);
|
||||
ps_spill(env, true, true);
|
||||
ps_spill(env, PS_FORCE_FX);
|
||||
|
||||
cs->exception_index = E2K_EXCP_MAPERR;
|
||||
cpu_loop_exit_restore(cs, retaddr);
|
||||
|
|
|
@ -48,10 +48,10 @@ uint64_t helper_state_reg_read_i64(CPUE2KState *env, int idx)
|
|||
case 0x13: return env->pcshtp; /* %pcshtp */
|
||||
case 0x2c: return env->usd.hi; /* %usd.hi */
|
||||
case 0x2d: return env->usd.lo; /* %usd.lo */
|
||||
case 0x51: return env->cr0_hi; /* %cr0.hi */
|
||||
case 0x53: return env->cr0_lo; /* %cr0.lo */
|
||||
case 0x55: return env->cr1.hi; /* %cr1.hi */
|
||||
case 0x57: return env->cr1.lo; /* %cr1.lo */
|
||||
case 0x51: return env->crs.cr0_hi; /* %cr0.hi */
|
||||
case 0x53: return env->crs.cr0_lo; /* %cr0.lo */
|
||||
case 0x55: return env->crs.cr1.hi; /* %cr1.hi */
|
||||
case 0x57: return env->crs.cr1.lo; /* %cr1.lo */
|
||||
case 0x81: return env->ip; /* %ip */
|
||||
case 0x85: return env->fpcr.raw; /* %fpcr */
|
||||
case 0x86: return env->fpsr.raw; /* %fpsr */
|
||||
|
|
Loading…
Reference in New Issue