e2k: cpu always spill/fill 32 bytes for every 2 regs
This commit is contained in:
parent
e381e6d3f5
commit
5afa8efc6e
|
@ -43,7 +43,7 @@ static inline void cpu_clone_regs_child(CPUE2KState *env, target_ulong newsp,
|
|||
return;
|
||||
}
|
||||
|
||||
frame_size = crs.cr1.wbs * (crs.cr1.wfx || E2K_FORCE_FX ? 32 : 16);
|
||||
frame_size = crs.cr1.wbs * 32;
|
||||
ps_base -= frame_size;
|
||||
ps.index += frame_size;
|
||||
ps_old = lock_user(VERIFY_READ, ps_base, frame_size, 1);
|
||||
|
|
|
@ -7074,8 +7074,7 @@ static abi_long do_e2k_longjmp2(CPUE2KState *env, struct target_jmp_info *jmp_in
|
|||
return ret;
|
||||
}
|
||||
psize = crs.cr1.wpsz * 2;
|
||||
ps_index -= crs.cr1.wbs * E2K_REG_LEN *
|
||||
(crs.cr1.wfx || E2K_FORCE_FX ? 4 : 2);
|
||||
ps_index -= crs.cr1.wbs * E2K_REG_LEN * 4;
|
||||
pcsp -= CRS_SIZE;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,14 +20,6 @@ void e2k_tcg_initialize(void);
|
|||
|
||||
/* #define TARGET_E2K_PRECISE_FSQRTID */
|
||||
|
||||
|
||||
/* FIXME: nfx window mode
|
||||
* numas13: I don't know why elbrus always spill/fill in fx mode.
|
||||
* If we enable 'nfx' mode It will break "finish" command in gdb because
|
||||
* it will try to read registers from hell.
|
||||
*/
|
||||
#define E2K_FORCE_FX true
|
||||
|
||||
#define GEN_MASK(start, len) (((1ULL << (len)) - 1) << (start))
|
||||
#define GET_BIT(v, index) (((v) >> (index)) & 1)
|
||||
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
#include "qemu/host-utils.h"
|
||||
#include "exec/helper-proto.h"
|
||||
|
||||
#define FRAME_SIZE(NREGS) ((NREGS) * 16)
|
||||
|
||||
static inline void reset_ctprs(CPUE2KState *env)
|
||||
{
|
||||
unsigned int i;
|
||||
|
@ -12,87 +14,97 @@ static inline void reset_ctprs(CPUE2KState *env)
|
|||
}
|
||||
}
|
||||
|
||||
static inline void ps_push(CPUE2KState *env, uint64_t value, uint8_t tag)
|
||||
static inline void ps_write(CPUE2KState *env, uint64_t value, uint8_t tag, int32_t index)
|
||||
{
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
if ((env->psp.index + 8) > env->psp.size) {
|
||||
raise_exception(env, E2K_EXCP_PROC_STACK_BOUNDS);
|
||||
}
|
||||
#endif
|
||||
cpu_stq_le_data(env, env->psp.base + index, value);
|
||||
|
||||
cpu_stq_le_data(env, env->psp.base + env->psp.index, value);
|
||||
if (env->enable_tags) {
|
||||
cpu_stb_data(env, env->psp.base_tag + env->psp.index / 8, tag);
|
||||
cpu_stb_data(env, env->psp.base_tag + index / 8, tag);
|
||||
}
|
||||
env->psp.index += 8;
|
||||
}
|
||||
|
||||
static inline uint64_t ps_pop(CPUE2KState *env, uint8_t *ret_tag)
|
||||
static inline uint64_t ps_read(CPUE2KState *env, uint8_t *ret_tag, int32_t index)
|
||||
{
|
||||
if (env->psp.index < 8) {
|
||||
raise_exception(env, E2K_EXCP_PROC_STACK_BOUNDS);
|
||||
}
|
||||
env->psp.index -= 8;
|
||||
if (ret_tag != NULL) {
|
||||
if (env->enable_tags) {
|
||||
abi_ptr ptr = env->psp.base_tag + env->psp.index / 8;
|
||||
*ret_tag = cpu_ldub_data(env, ptr);
|
||||
*ret_tag = cpu_ldub_data(env, env->psp.base_tag + index / 8);
|
||||
} else {
|
||||
*ret_tag = 0;
|
||||
}
|
||||
}
|
||||
return cpu_ldq_le_data(env, env->psp.base + env->psp.index);
|
||||
}
|
||||
|
||||
return cpu_ldq_le_data(env, env->psp.base + index);
|
||||
}
|
||||
|
||||
static void ps_spill(CPUE2KState *env, int n, bool fx)
|
||||
{
|
||||
int i;
|
||||
int32_t index = env->psp.index;
|
||||
|
||||
// XXX: psp.size is set to some random value and does not show real stack size
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
if (env->psp.index + FRAME_SIZE(n) > env->psp.size) {
|
||||
raise_exception(env, E2K_EXCP_PROC_STACK_BOUNDS);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (env->version >= 5) {
|
||||
for (i = 0; i < n; i++) {
|
||||
ps_push(env, env->regs[i].lo, env->tags[i]);
|
||||
if (fx || E2K_FORCE_FX) {
|
||||
ps_push(env, env->regs[i].hi, 0);
|
||||
for (int i = 0; i < n; i++, index += 16) {
|
||||
ps_write(env, env->regs[i].lo, env->tags[i], index);
|
||||
|
||||
if (fx) {
|
||||
ps_write(env, env->regs[i].hi, 0, index + 8);
|
||||
}
|
||||
}
|
||||
} else{
|
||||
for (i = 0; i < n; i += 2) {
|
||||
for (int i = 0; i < n; i += 2, index += 32) {
|
||||
E2KReg r0 = env->regs[i + 0];
|
||||
E2KReg r1 = env->regs[i + 1];
|
||||
ps_push(env, r0.lo, env->tags[i]);
|
||||
ps_push(env, r1.lo, env->tags[i + 1]);
|
||||
if (fx || E2K_FORCE_FX) {
|
||||
ps_push(env, r0.hi, 0);
|
||||
ps_push(env, r1.hi, 0);
|
||||
|
||||
ps_write(env, r0.lo, env->tags[i], index);
|
||||
ps_write(env, r1.lo, env->tags[i + 1], index + 8);
|
||||
|
||||
if (fx) {
|
||||
ps_write(env, r0.hi, 0, index + 16);
|
||||
ps_write(env, r1.hi, 0, index + 24);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
env->psp.index = index;
|
||||
}
|
||||
|
||||
static void ps_fill(CPUE2KState *env, int n, bool fx)
|
||||
{
|
||||
int i;
|
||||
int32_t index = env->psp.index, frame_size = FRAME_SIZE(n);
|
||||
|
||||
if (index < frame_size) {
|
||||
raise_exception(env, E2K_EXCP_PROC_STACK_BOUNDS);
|
||||
}
|
||||
|
||||
if (env->version >= 5) {
|
||||
for (i = n; i-- > 0;) {
|
||||
if (fx || E2K_FORCE_FX) {
|
||||
env->regs[i].hi = ps_pop(env, NULL);
|
||||
for (int i = n; i-- > 0; index -= 16) {
|
||||
if (fx) {
|
||||
env->regs[i].hi = ps_read(env, NULL, index - 8);
|
||||
}
|
||||
env->regs[i].lo = ps_pop(env, &env->tags[i]);
|
||||
|
||||
env->regs[i].lo = ps_read(env, &env->tags[i], index - 16);
|
||||
}
|
||||
} else {
|
||||
for (i = n; i > 0; i -= 2) {
|
||||
for (int i = n; i > 0; i -= 2, index -= 32) {
|
||||
E2KReg *r0 = &env->regs[i - 1];
|
||||
E2KReg *r1 = &env->regs[i - 2];
|
||||
if (fx || E2K_FORCE_FX) {
|
||||
r0->hi = ps_pop(env, NULL);
|
||||
r1->hi = ps_pop(env, NULL);
|
||||
|
||||
if (fx) {
|
||||
r0->hi = ps_read(env, NULL, index - 8);
|
||||
r1->hi = ps_read(env, NULL, index - 16);
|
||||
}
|
||||
r0->lo = ps_pop(env, &env->tags[i - 1]);
|
||||
r1->lo = ps_pop(env, &env->tags[i - 2]);
|
||||
|
||||
r0->lo = ps_read(env, &env->tags[i - 1], index - 24);
|
||||
r1->lo = ps_read(env, &env->tags[i - 2], index - 32);
|
||||
}
|
||||
}
|
||||
|
||||
env->psp.index = index;
|
||||
}
|
||||
|
||||
static void move_regs(CPUE2KState *env, int dst, int src, int n)
|
||||
|
|
|
@ -94,7 +94,6 @@ typedef enum {
|
|||
} AlesFlag;
|
||||
|
||||
static TCGv cpu_pc;
|
||||
static TCGv cpu_npc;
|
||||
static TCGv_i64 cpu_ctprs[3];
|
||||
static TCGv_i32 cpu_ct_cond;
|
||||
static TCGv_i32 cpu_boff; /* holds rbs * 2 */
|
||||
|
@ -7550,7 +7549,6 @@ void e2k_tcg_initialize(void) {
|
|||
|
||||
static const struct { TCGv *ptr; int off; const char *name; } rtl[] = {
|
||||
{ &cpu_pc, offsetof(CPUE2KState, ip), "pc" },
|
||||
{ &cpu_npc, offsetof(CPUE2KState, nip), "npc" },
|
||||
};
|
||||
|
||||
unsigned int i;
|
||||
|
|
Loading…
Reference in New Issue