diff --git a/target/e2k/cpu.h b/target/e2k/cpu.h index d44ac1095a..fc57be3e2a 100644 --- a/target/e2k/cpu.h +++ b/target/e2k/cpu.h @@ -25,16 +25,14 @@ typedef struct CPUArchState { target_ulong wregs[WREGS_SIZE]; // window regs target_ulong *win_ptr; uint64_t pregs; - unsigned int wbs; // window regs offset (* 2) - unsigned int wsz; // window regs size (* 2) - unsigned int nfx; // TODO - unsigned int dbl; // TODO - unsigned int rbs; // based regs offset (* 2) - unsigned int rsz; // based regs window size (* 2 + 2) - unsigned int rcur; // based regs current index (* 2) - unsigned int psz; // pred regs window size - - unsigned int is_jmp; + uint32_t wbs; // window regs offset (* 2) + uint32_t wsz; // window regs size (* 2) + uint32_t nfx; // TODO + uint32_t dbl; // TODO + uint32_t rbs; // based regs offset (* 2) + uint32_t rsz; // based regs window size (* 2 + 2) + uint32_t rcur; // based regs current index (* 2) + uint32_t psz; // pred regs window size /* control registers */ target_ulong ctprs[3]; // Control Transfer Preparation Register (CTPR) diff --git a/target/e2k/translate.h b/target/e2k/translate.h index 7ac6206104..007f2bab8b 100644 --- a/target/e2k/translate.h +++ b/target/e2k/translate.h @@ -6,9 +6,10 @@ #define STATIC_JUMP DISAS_TARGET_0 #define DYNAMIC_JUMP DISAS_TARGET_1 +#define GEN_MASK(start, end) (((1 << ((end) - (start) + 1)) - 1) << start) #define GET_BIT(v, index) (((v) >> (index)) & 1) #define GET_FIELD(v, start, end) \ - (((v) >> (start)) & ((1 << ((end) - (start) + 1)) - 1)) + (((v) & GEN_MASK(start, end)) >> (start)) #define IS_BASED(i) (((i) & 0x80) == 0) #define IS_REGULAR(i) (((i) & 0xc0) == 0x80) @@ -147,6 +148,33 @@ static inline void e2k_gen_wrap_i32(TCGv_i32 ret, TCGv_i32 x, TCGv_i32 y) tcg_temp_free_i32(t0); } +static inline void e2k_gen_get_field_i64(TCGv_i64 ret, TCGv_i64 val, + unsigned int start, unsigned int end) +{ + TCGv_i64 t0 = tcg_temp_new_i64(); + + tcg_gen_and_i64(t0, val, GEN_MASK(start, end)); + tcg_gen_shli_i64(ret, t0, start); + + tcg_temp_free_i64(t0); +} + +static inline void e2k_gen_set_field_i64(TCGv_i64 ret, TCGv_i64 val, + uint64_t field, unsigned int start, unsigned int end) +{ + uint64_t mask = GEN_MASK(start, end); + TCGv_i64 t0 = tcg_const_i64(~mask); + TCGv_i64 t1 = tcg_const_i64((field << start) & mask); + TCGv_i64 t2 = tcg_temp_new_i64(); + + tcg_gen_and_i64(t2, val, t0); + tcg_gen_or_i64(ret, t2, t1); + + tcg_temp_free_i64(t2); + tcg_temp_free_i64(t1); + tcg_temp_free_i64(t0); +} + TCGv_i64 e2k_get_preg(DisasContext *dc, int reg); void e2k_gen_store_preg(int reg, TCGv_i64 val); TCGv_i64 e2k_get_wreg(DisasContext *dc, int reg); diff --git a/target/e2k/translate/control.c b/target/e2k/translate/control.c index 62133e46d7..da6003c379 100644 --- a/target/e2k/translate/control.c +++ b/target/e2k/translate/control.c @@ -85,7 +85,7 @@ static void gen_cs0(DisasContext *dc) if (type == DISP || type == SDISP || type == LDISP) { /* TODO: SDISP tag */ - unsigned int disp = (cs0 & 0x0fffffff); + unsigned int disp = GET_FIELD(cs0, 0, 27); /* Calculate a signed displacement in bytes. */ int sdisp = ((int) (disp << 4)) >> 1; target_ulong tgt = dc->pc + sdisp; diff --git a/target/e2k/translate/win.c b/target/e2k/translate/win.c index 32bcd6e7a3..e9f5a79874 100644 --- a/target/e2k/translate/win.c +++ b/target/e2k/translate/win.c @@ -10,13 +10,16 @@ static inline void gen_abn_inc(DisasContext *dc, TCGCond cond) TCGv_i32 t0 = tcg_temp_new_i32(); TCGv_i32 t1 = tcg_temp_new_i32(); TCGv_i32 one = tcg_const_i32(1); + TCGv_i32 jmp_cond = tcg_temp_new_i32(); tcg_gen_addi_i32(t0, e2k_cs.rcur, 2); e2k_gen_wrap_i32(t1, t0, e2k_cs.rsz); + tcg_gen_extrl_i64_i32(jmp_cond, dc->jmp.cond); tcg_gen_movcond_i32(cond, e2k_cs.rcur, - dc->jmp.cond, one, + jmp_cond, one, t1, e2k_cs.rcur); + tcg_temp_free_i32(jmp_cond); tcg_temp_free_i32(one); tcg_temp_free_i32(t1); tcg_temp_free_i32(t0);