target: e2k: Add dbl window modifier.
This commit is contained in:
parent
2446fbf44c
commit
5b444c9356
|
@ -523,8 +523,12 @@ typedef struct CPUArchState {
|
|||
E2KAauState aau;
|
||||
|
||||
int interrupt_index;
|
||||
|
||||
/* internal use */
|
||||
uint32_t is_bp; /* breakpoint flag */
|
||||
int syscall_wbs; // FIXME: temp for syscall
|
||||
/* zeroing upper register half for 32-bit instructions */
|
||||
uint32_t wdbl;
|
||||
|
||||
/* Fields up to this point are cleared by a CPU reset */
|
||||
struct {} end_reset_fields;
|
||||
|
|
|
@ -96,6 +96,7 @@ static inline void proc_chain_restore(CPUE2KState *env)
|
|||
env->wd.psize = env->cr1.wpsz * 2;
|
||||
env->wd.base = (E2K_NR_COUNT + env->wd.base - wbs * 2) % E2K_NR_COUNT;
|
||||
env->wd.fx = env->cr1.wfx;
|
||||
env->wdbl = env->cr1.wdbl;
|
||||
|
||||
env->pshtp.index -= wbs * 2;
|
||||
|
||||
|
@ -155,12 +156,8 @@ void helper_setwd(CPUE2KState *env, uint32_t lts)
|
|||
|
||||
if (env->version >= 3) {
|
||||
bool dbl = extract32(lts, 3, 1);
|
||||
// TODO: set dbl
|
||||
if (dbl != false) {
|
||||
qemu_log_mask(LOG_UNIMP, "0x%lx: dbl is not implemented!\n",
|
||||
env->ip);
|
||||
}
|
||||
env->cr1.wdbl = dbl;
|
||||
env->wdbl = dbl;
|
||||
}
|
||||
|
||||
ps_spill(env, false, PS_FORCE_FX);
|
||||
|
|
|
@ -462,6 +462,7 @@ void e2k_tcg_initialize(void) {
|
|||
{ &e2k_cs.psize, offsetof(CPUE2KState, bp.size), "psize" },
|
||||
{ &e2k_cs.pcur, offsetof(CPUE2KState, bp.cur), "pcur" },
|
||||
{ &e2k_cs.is_bp, offsetof(CPUE2KState, is_bp), "is_bp" },
|
||||
{ &e2k_cs.wdbl, offsetof(CPUE2KState, wdbl), "wdbl" },
|
||||
{ &e2k_cs.aasti_tags, offsetof(CPUE2KState, aau.sti_tags), "aasti_tags" },
|
||||
{ &e2k_cs.aaind_tags, offsetof(CPUE2KState, aau.ind_tags), "aaind_tags" },
|
||||
{ &e2k_cs.aaincr_tags, offsetof(CPUE2KState, aau.incr_tags), "aaincr_tags" },
|
||||
|
|
|
@ -39,6 +39,7 @@ typedef struct CPUE2KStateTCG {
|
|||
TCGv_i64 ctprs[3];
|
||||
TCGv_i32 ct_cond;
|
||||
TCGv_i32 is_bp; /* breakpoint flag */
|
||||
TCGv_i32 wdbl;
|
||||
TCGv_i64 lsr;
|
||||
TCGv_i64 regs[E2K_REG_COUNT];
|
||||
TCGv_i64 tags[E2K_TAGS_REG_COUNT];
|
||||
|
@ -100,6 +101,10 @@ typedef enum {
|
|||
|
||||
typedef struct {
|
||||
AlResultType type;
|
||||
/* check tag for 32-bit ops if wdbl is set */
|
||||
bool check_tag;
|
||||
/* poison result if tag is not zero */
|
||||
bool poison;
|
||||
union {
|
||||
struct {
|
||||
uint8_t dst; /* %rN, 1st phase */
|
||||
|
|
|
@ -353,11 +353,12 @@ static inline void gen_dst_poison_i32(TCGv_i32 ret, TCGv_i32 value,
|
|||
}
|
||||
|
||||
static inline void set_al_result_reg64_tag(DisasContext *ctx, int chan,
|
||||
TCGv_i64 value, TCGv_i32 tag)
|
||||
TCGv_i64 value, TCGv_i32 tag, bool poison)
|
||||
{
|
||||
uint8_t arg = extract32(ctx->bundle.als[chan], 0, 8);
|
||||
AlResult *res = &ctx->al_results[chan];
|
||||
|
||||
res->poison = poison;
|
||||
// TODO: %tst, %tc, %tcd
|
||||
if (arg == 0xdf) { /* %empty */
|
||||
res->type = AL_RESULT_NONE;
|
||||
|
@ -387,15 +388,17 @@ static inline void set_al_result_reg64_tag(DisasContext *ctx, int chan,
|
|||
static inline void set_al_result_reg64(DisasContext *ctx, int chan,
|
||||
TCGv_i64 value)
|
||||
{
|
||||
set_al_result_reg64_tag(ctx, chan, value, e2k_get_const_i32(ctx, 0));
|
||||
set_al_result_reg64_tag(ctx, chan, value, e2k_get_const_i32(ctx, 0), true);
|
||||
}
|
||||
|
||||
static inline void set_al_result_reg32_tag(DisasContext *ctx, int chan,
|
||||
TCGv_i32 value, TCGv_i32 tag)
|
||||
TCGv_i32 value, TCGv_i32 tag, bool poison, bool check_tag)
|
||||
{
|
||||
uint8_t arg = extract32(ctx->bundle.als[chan], 0, 8);
|
||||
AlResult *res = &ctx->al_results[chan];
|
||||
|
||||
res->check_tag = check_tag;
|
||||
res->poison = poison;
|
||||
// TODO: %tst, %tc, %tcd
|
||||
if (arg == 0xdf) { /* %empty */
|
||||
res->type = AL_RESULT_NONE;
|
||||
|
@ -424,7 +427,8 @@ static inline void set_al_result_reg32_tag(DisasContext *ctx, int chan,
|
|||
static inline void set_al_result_reg32(DisasContext *ctx, int chan,
|
||||
TCGv_i32 value)
|
||||
{
|
||||
set_al_result_reg32_tag(ctx, chan, value, e2k_get_const_i32(ctx, 0));
|
||||
set_al_result_reg32_tag(ctx, chan, value, e2k_get_const_i32(ctx, 0), true,
|
||||
true);
|
||||
}
|
||||
|
||||
static inline void set_al_result_preg(DisasContext *ctx, int chan, int index,
|
||||
|
@ -442,8 +446,7 @@ static inline void gen_al_result_i64(DisasContext *ctx, int chan, TCGv_i64 dst,
|
|||
{
|
||||
bool sm = extract32(ctx->bundle.als[chan], 31, 1);
|
||||
gen_tag_check(ctx, sm, tag);
|
||||
gen_dst_poison_i64(dst, dst, tag);
|
||||
set_al_result_reg64_tag(ctx, chan, dst, tag);
|
||||
set_al_result_reg64_tag(ctx, chan, dst, tag, true);
|
||||
}
|
||||
|
||||
static inline void gen_al_result_i32(DisasContext *ctx, int chan, TCGv_i32 dst,
|
||||
|
@ -451,8 +454,7 @@ static inline void gen_al_result_i32(DisasContext *ctx, int chan, TCGv_i32 dst,
|
|||
{
|
||||
bool sm = extract32(ctx->bundle.als[chan], 31, 1);
|
||||
gen_tag_check(ctx, sm, tag);
|
||||
gen_dst_poison_i32(dst, dst, tag);
|
||||
set_al_result_reg32_tag(ctx, chan, dst, tag);
|
||||
set_al_result_reg32_tag(ctx, chan, dst, tag, true, true);
|
||||
}
|
||||
|
||||
static inline bool is_mrgc(uint16_t rlp, int chan)
|
||||
|
@ -1125,7 +1127,7 @@ static inline void gen_puttag_i64(DisasContext *ctx, int chan)
|
|||
gen_set_label(l0);
|
||||
tcg_gen_mov_i32(tag, s2.value);
|
||||
gen_set_label(l1);
|
||||
set_al_result_reg64_tag(ctx, chan, dst, tag);
|
||||
set_al_result_reg64_tag(ctx, chan, dst, tag, false);
|
||||
}
|
||||
|
||||
static inline void gen_puttag_i32(DisasContext *ctx, int chan)
|
||||
|
@ -1148,7 +1150,7 @@ static inline void gen_puttag_i32(DisasContext *ctx, int chan)
|
|||
gen_set_label(l0);
|
||||
tcg_gen_mov_i32(tag, s2.value);
|
||||
gen_set_label(l1);
|
||||
set_al_result_reg32_tag(ctx, chan, dst, tag);
|
||||
set_al_result_reg32_tag(ctx, chan, dst, tag, false, false);
|
||||
}
|
||||
|
||||
static inline void gen_insert_field_i64(TCGv_i64 ret, TCGv_i64 src1,
|
||||
|
@ -1329,7 +1331,7 @@ static void gen_getsp(DisasContext *ctx, int chan)
|
|||
static void gen_movtd(DisasContext *ctx, int chan)
|
||||
{
|
||||
Src64 s2 = get_src2_i64(ctx, chan);
|
||||
set_al_result_reg64_tag(ctx, chan, s2.value, s2.tag);
|
||||
set_al_result_reg64_tag(ctx, chan, s2.value, s2.tag, false);
|
||||
}
|
||||
|
||||
static MemOp gen_mas(DisasContext *ctx, int chan, MemOp memop, TCGv_i64 addr)
|
||||
|
@ -2954,13 +2956,56 @@ void e2k_alc_commit(DisasContext *ctx)
|
|||
}
|
||||
|
||||
switch(res->type) {
|
||||
case AL_RESULT_REG32:
|
||||
case AL_RESULT_REG32: {
|
||||
TCGLabel *l0 = gen_new_label();
|
||||
TCGLabel *l1 = gen_new_label();
|
||||
TCGv_i32 t0 = tcg_temp_new_i32();
|
||||
TCGv_i64 t1 = tcg_temp_new_i64();
|
||||
|
||||
tcg_gen_brcondi_i32(TCG_COND_NE, e2k_cs.wdbl, 0, l0);
|
||||
|
||||
e2k_gen_reg_tag_write_i32(res->reg.tag, res->reg.index);
|
||||
e2k_gen_reg_write_i32(res->reg.v32, res->reg.index);
|
||||
if (res->poison) {
|
||||
gen_dst_poison_i32(t0, res->reg.v32, res->reg.tag);
|
||||
e2k_gen_reg_write_i32(t0, res->reg.index);
|
||||
} else {
|
||||
e2k_gen_reg_write_i32(res->reg.v32, res->reg.index);
|
||||
}
|
||||
tcg_gen_br(l1);
|
||||
|
||||
gen_set_label(l0);
|
||||
if (res->check_tag) {
|
||||
gen_tag1_i64(t0, res->reg.tag);
|
||||
e2k_gen_reg_tag_write_i64(t0, res->reg.index);
|
||||
} else {
|
||||
e2k_gen_reg_tag_write_i64(res->reg.tag, res->reg.index);
|
||||
}
|
||||
tcg_gen_extu_i32_i64(t1, res->reg.v32);
|
||||
if (res->poison) {
|
||||
TCGv_i64 t2 = tcg_temp_new_i64();
|
||||
gen_dst_poison_i64(t2, t1, t0);
|
||||
e2k_gen_reg_write_i64(t2, res->reg.index);
|
||||
tcg_temp_free_i64(t2);
|
||||
} else {
|
||||
e2k_gen_reg_write_i64(t1, res->reg.index);
|
||||
}
|
||||
|
||||
gen_set_label(l1);
|
||||
|
||||
tcg_temp_free_i64(t1);
|
||||
tcg_temp_free_i32(t0);
|
||||
break;
|
||||
}
|
||||
case AL_RESULT_REG64:
|
||||
e2k_gen_reg_tag_write_i64(res->reg.tag, res->reg.index);
|
||||
e2k_gen_reg_write_i64(res->reg.v64, res->reg.index);
|
||||
if (res->poison) {
|
||||
TCGv_i64 t0 = tcg_temp_new_i64();
|
||||
gen_dst_poison_i64(t0, res->reg.v64, res->reg.tag);
|
||||
e2k_gen_reg_write_i64(t0, res->reg.index);
|
||||
tcg_temp_free_i64(t0);
|
||||
} else {
|
||||
e2k_gen_reg_write_i64(res->reg.v64, res->reg.index);
|
||||
}
|
||||
break;
|
||||
case AL_RESULT_PREG:
|
||||
e2k_gen_store_preg(res->preg.index, res->preg.value);
|
||||
|
|
Loading…
Reference in New Issue