diff --git a/target/e2k/cpu.c b/target/e2k/cpu.c index faeaac42ad..be314b0e7c 100644 --- a/target/e2k/cpu.c +++ b/target/e2k/cpu.c @@ -69,6 +69,23 @@ static const struct e2k_def_t e2k_defs[] = { } }; +static inline void cpu_dump_state_br(CPUE2KState *env, FILE *f, int flags) +{ + uint32_t br = env->br; + int rbs = GET_FIELD(br, BR_RBS_OFF, BR_RBS_LEN); + int rsz = GET_FIELD(br, BR_RSZ_OFF, BR_RSZ_LEN); + int rcur = GET_FIELD(br, BR_RCUR_OFF, BR_RCUR_LEN); + int psz = GET_FIELD(br, BR_PSZ_OFF, BR_PSZ_LEN); + int pcur = GET_FIELD(br, BR_PCUR_OFF, BR_PCUR_LEN); + + qemu_fprintf(f, "br %#x\n", br); + qemu_fprintf(f, " rbs %#x\n", rbs); + qemu_fprintf(f, " rsz %#x\n", rsz); + qemu_fprintf(f, " rcur %#x\n", rcur); + qemu_fprintf(f, " psz %#x\n", psz); + qemu_fprintf(f, " pcur %#x\n", pcur); +} + void e2k_cpu_dump_state(CPUState *cs, FILE *f, int flags) { E2KCPU *cpu = E2K_CPU(cs); @@ -80,9 +97,7 @@ void e2k_cpu_dump_state(CPUState *cs, FILE *f, int flags) qemu_fprintf(f, "usd_hi: %016lx, usd_lo: %016lx\n", env->usd_hi, env->usd_lo); qemu_fprintf(f, "wbs: %d, wsz: %d\n", (int) env->wbs, (int) env->wsz); - qemu_fprintf(f, "rbs: %d, rsz: %d, rcur: %d\n", - (int) env->rbs, (int) env->rsz, (int) env->rcur); - qemu_fprintf(f, "psz: %d, pcur: %d\n", (int) env->psz, (int) env->pcur); + cpu_dump_state_br(env, f, flags); qemu_fprintf(f, "lsr: %016lx\n", env->lsr); for (i = 0; i < 192; i += 4) { diff --git a/target/e2k/cpu.h b/target/e2k/cpu.h index 278a2ac073..acc5a347b4 100644 --- a/target/e2k/cpu.h +++ b/target/e2k/cpu.h @@ -7,6 +7,12 @@ void e2k_tcg_initialize(void); +#define GEN_MASK(start, end) \ + (((1UL << ((end) - (start) + 1)) - 1) << start) +#define GET_BIT(v, index) (((v) >> (index)) & 1) +#define GET_FIELD(v, start, end) \ + (((v) >> (start)) & ((1UL << ((end) - (start) + 1)) - 1)) + #define MMU_USER_IDX 1 #define CPU_RESOLVING_TYPE TYPE_E2K_CPU #define WREGS_SIZE 192 @@ -22,6 +28,28 @@ void e2k_tcg_initialize(void); #define CTPR_IPD_OFF 59 #define CTPR_IPD_END 60 +#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_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_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_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_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 LSR_LCNT_OFF 0 /* loop counter */ #define LSR_LCNT_END 31 #define LSR_LCNT_LEN (LSR_LCNT_END - LSR_LCNT_OFF + 1) @@ -65,13 +93,7 @@ typedef struct { uint32_t nfx; // TODO uint32_t dbl; // TODO - /* TODO: move them to %br? */ - uint32_t rbs; // based regs offset - uint32_t rsz; // based regs size - uint32_t rcur; // based regs current offset - uint64_t psz; // pred regs window size - uint64_t pcur; // pred regs current offset - + uint32_t br; /* based regs and pregs window registers */ uint64_t lsr; /* loop status register */ uint32_t syscall_wbs; diff --git a/target/e2k/helper.c b/target/e2k/helper.c index 054341a8e6..d55783a1a8 100644 --- a/target/e2k/helper.c +++ b/target/e2k/helper.c @@ -14,7 +14,7 @@ void helper_raise_exception(CPUE2KState *env, int tt) cpu_loop_exit(cs); } -void helper_call(CPUE2KState *env, uint64_t ctpr, uint64_t cond) +void helper_call(CPUE2KState *env, target_ulong ctpr, target_ulong cond) { int tag = GET_FIELD(ctpr, CTPR_TAG_OFF, CTPR_TAG_END); if (!cond) { diff --git a/target/e2k/helper.h b/target/e2k/helper.h index be9e7ca65e..9269f443e9 100644 --- a/target/e2k/helper.h +++ b/target/e2k/helper.h @@ -1,5 +1,5 @@ DEF_HELPER_2(raise_exception, noreturn, env, int) -DEF_HELPER_3(call, void, env, i64, i64) +DEF_HELPER_3(call, void, env, tl, tl) DEF_HELPER_2(sxt, i64, i64, i64) DEF_HELPER_1(debug_i32, void, i32) DEF_HELPER_1(debug_i64, void, i64) diff --git a/target/e2k/translate.c b/target/e2k/translate.c index 43ac66a8a1..7f9a12d3c3 100644 --- a/target/e2k/translate.c +++ b/target/e2k/translate.c @@ -188,7 +188,7 @@ static target_ulong unpack_bundle(CPUE2KState *env, static inline void save_state(DisasContext *dc) { tcg_gen_movi_tl(e2k_cs.pc, dc->pc); - tcg_gen_movi_tl(e2k_cs.pc, dc->npc); +// tcg_gen_movi_tl(e2k_cs.pc, dc->npc); } void e2k_gen_exception(DisasContext *dc, int which) @@ -287,18 +287,18 @@ static void e2k_tr_tb_stop(DisasContextBase *db, CPUState *cs) break; } case STATIC_JUMP: - tcg_gen_mov_i64(e2k_cs.pc, dc->jmp.dest); + tcg_gen_mov_tl(e2k_cs.pc, dc->jmp.dest); tcg_gen_exit_tb(NULL, 0); break; case DYNAMIC_JUMP: { - TCGv_i64 one = tcg_const_i64(1); - TCGv_i64 npc = tcg_const_i64(dc->npc); - tcg_gen_movcond_i64(TCG_COND_EQ, e2k_cs.pc, + TCGv_i64 one = tcg_const_tl(1); + TCGv_i64 npc = tcg_const_tl(dc->npc); + tcg_gen_movcond_tl(TCG_COND_EQ, e2k_cs.pc, dc->jmp.cond, one, dc->jmp.dest, npc ); - tcg_temp_free_i64(npc); - tcg_temp_free_i64(one); + tcg_temp_free(npc); + tcg_temp_free(one); tcg_gen_exit_tb(NULL, 0); break; } @@ -307,8 +307,8 @@ static void e2k_tr_tb_stop(DisasContextBase *db, CPUState *cs) break; } - tcg_temp_free_i64(dc->jmp.dest); - tcg_temp_free_i64(dc->jmp.cond); + tcg_temp_free(dc->jmp.dest); + tcg_temp_free(dc->jmp.cond); } static void e2k_tr_disas_log(const DisasContextBase *db, CPUState *cpu) @@ -351,16 +351,12 @@ void e2k_tcg_initialize(void) { { &e2k_cs.wsz, offsetof(CPUE2KState, wsz), "wsz" }, { &e2k_cs.nfx, offsetof(CPUE2KState, nfx), "nfx" }, { &e2k_cs.dbl, offsetof(CPUE2KState, dbl), "dbl" }, - { &e2k_cs.rbs, offsetof(CPUE2KState, rbs), "rbs" }, - { &e2k_cs.rsz, offsetof(CPUE2KState, rsz), "rsz" }, - { &e2k_cs.rcur, offsetof(CPUE2KState, rcur), "rcur" }, + { &e2k_cs.br, offsetof(CPUE2KState, br), "br" }, { &e2k_cs.syscall_wbs, offsetof(CPUE2KState, syscall_wbs), "syscall_wbs" }, }; static const struct { TCGv_i64 *ptr; int off; const char *name; } r64[] = { { &e2k_cs.pregs, offsetof(CPUE2KState, pregs), "pregs" }, - { &e2k_cs.psz, offsetof(CPUE2KState, psz), "psz" }, - { &e2k_cs.pcur, offsetof(CPUE2KState, pcur), "pcur" }, { &e2k_cs.usd_lo, offsetof(CPUE2KState, usd_lo), "usd.lo" }, { &e2k_cs.usd_hi, offsetof(CPUE2KState, usd_hi), "usd.hi" }, { &e2k_cs.lsr, offsetof(CPUE2KState, lsr), "lsr" }, diff --git a/target/e2k/translate.h b/target/e2k/translate.h index 5a8598f670..e0144bb506 100644 --- a/target/e2k/translate.h +++ b/target/e2k/translate.h @@ -8,12 +8,6 @@ #define DYNAMIC_JUMP DISAS_TARGET_1 #define DISAS_CALL DISAS_TARGET_2 -#define GEN_MASK(start, end) \ - (((1UL << ((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)) - #define IS_BASED(i) (((i) & 0x80) == 0) #define IS_REGULAR(i) (((i) & 0xc0) == 0x80) #define IS_IMM5(i) (((i) & 0xe0) == 0xc0) @@ -56,11 +50,7 @@ typedef struct CPUE2KStateTCG { TCGv_i32 wsz; TCGv_i32 nfx; TCGv_i32 dbl; - TCGv_i32 rbs; - TCGv_i32 rsz; - TCGv_i32 rcur; - TCGv_i64 psz; - TCGv_i64 pcur; + TCGv_i32 br; TCGv_i64 lsr; TCGv_i32 syscall_wbs; TCGv_ptr win_ptr; diff --git a/target/e2k/translate/alc.c b/target/e2k/translate/alc.c index 043863d99d..c03937a038 100644 --- a/target/e2k/translate/alc.c +++ b/target/e2k/translate/alc.c @@ -506,7 +506,7 @@ static void gen_alopf_simple(DisasContext *dc, int chan) case 0x1d: /* sard */ gen_alopf1_i64(dc, chan, tcg_gen_sar_i64); break; case 0x1e: /* TODO: getfs */ abort(); break; case 0x1f: /* TODO: getfd */ abort(); break; - case 0x21: { // cmp{op}sd + case 0x21: { // cmp{op}db TCGv_i64 cpu_src1 = get_src1(dc, als); TCGv_i64 cpu_src2 = get_src2(dc, als); TCGv_i64 tmp_dst = e2k_get_temp_i64(dc); diff --git a/target/e2k/translate/control.c b/target/e2k/translate/control.c index f3597c3679..77d7faa6ca 100644 --- a/target/e2k/translate/control.c +++ b/target/e2k/translate/control.c @@ -3,7 +3,7 @@ #include "exec/log.h" #include "translate.h" -static inline void gen_alc_dec(DisasContext *dc, TCGCond cond) +static inline void gen_alc_dec(TCGCond cond, TCGv_i64 jmp_cond) { TCGv_i64 one = tcg_const_i64(1); TCGv_i32 zero = tcg_const_i32(0); @@ -24,9 +24,7 @@ static inline void gen_alc_dec(DisasContext *dc, TCGCond cond) tcg_gen_extrh_i64_i32(t5, e2k_cs.lsr); tcg_gen_or_i32(t6, t5, t4); tcg_gen_concat_i32_i64(t7, t2, t6); - tcg_gen_movcond_i64(cond, e2k_cs.lsr, - dc->jmp.cond, one, - t7, e2k_cs.lsr); + tcg_gen_movcond_i64(cond, e2k_cs.lsr, jmp_cond, one, t7, e2k_cs.lsr); tcg_temp_free_i64(t7); tcg_temp_free_i32(t6); @@ -40,100 +38,144 @@ static inline void gen_alc_dec(DisasContext *dc, TCGCond cond) tcg_temp_free_i64(one); } -static inline void gen_abp_inc(DisasContext *dc, TCGCond cond) +static inline void gen_pcur_inc(TCGv_i32 ret, TCGv_i32 br) { - TCGv_i64 t0 = tcg_temp_new_i64(); - TCGv_i64 t1 = tcg_temp_new_i64(); - TCGv_i64 one = tcg_const_i64(1); + TCGv_i32 pcur = tcg_temp_new_i32(); + TCGv_i32 psz = tcg_temp_new_i32(); + TCGv_i32 t0 = tcg_temp_new_i32(); + TCGv_i32 t1 = tcg_temp_new_i32(); - tcg_gen_subi_i64(t0, e2k_cs.pcur, 1); - tcg_gen_umin_i64(t1, t0, e2k_cs.psz); - tcg_gen_movcond_i64(cond, e2k_cs.pcur, dc->jmp.cond, one, t1, e2k_cs.pcur); + tcg_gen_extract_i32(pcur, br, BR_PCUR_OFF, BR_PCUR_LEN); + tcg_gen_extract_i32(psz, br, BR_PSZ_OFF, BR_PSZ_LEN); + tcg_gen_subi_i32(t0, pcur, 1); + tcg_gen_umin_i32(t1, t0, psz); + tcg_gen_deposit_i32(ret, br, t1, BR_PCUR_OFF, BR_PCUR_LEN); - tcg_temp_free_i64(one); - tcg_temp_free_i64(t1); - tcg_temp_free_i64(t0); + tcg_temp_free_i32(t1); + tcg_temp_free_i32(t0); + tcg_temp_free_i32(psz); + tcg_temp_free_i32(pcur); } -static inline void gen_abn_inc(DisasContext *dc, TCGCond cond) +static inline void gen_rcur_inc(TCGv_i32 ret, TCGv_i32 br) { + TCGv_i32 rcur = tcg_temp_new_i32(); + TCGv_i32 rsz = tcg_temp_new_i32(); TCGv_i32 t0 = tcg_temp_new_i32(); TCGv_i32 t1 = tcg_temp_new_i32(); TCGv_i32 t2 = tcg_temp_new_i32(); - TCGv_i32 t3 = tcg_temp_new_i32(); - TCGv_i32 one = tcg_const_i32(1); - tcg_gen_subi_i32(t0, e2k_cs.rcur, 1); - tcg_gen_umin_i32(t2, t0, e2k_cs.rsz); - tcg_gen_extrl_i64_i32(t3, dc->jmp.cond); - tcg_gen_movcond_i32(cond, e2k_cs.rcur, - t3, one, - t2, e2k_cs.rcur); + tcg_gen_extract_i32(rcur, br, BR_RCUR_OFF, BR_RCUR_LEN); + tcg_gen_extract_i32(rsz, br, BR_RSZ_OFF, BR_RSZ_LEN); + tcg_gen_subi_i32(t0, rcur, 1); + tcg_gen_umin_i32(t2, t0, rsz); + tcg_gen_deposit_i32(ret, br, t2, BR_RCUR_OFF, BR_RCUR_LEN); - tcg_temp_free_i32(one); - tcg_temp_free_i32(t3); tcg_temp_free_i32(t2); tcg_temp_free_i32(t1); tcg_temp_free_i32(t0); + tcg_temp_free_i32(rsz); + tcg_temp_free_i32(rcur); +} + +static inline void gen_movcond_flag_i32(TCGv_i32 ret, int flag, TCGv_i32 cond, + TCGv_i32 v1, TCGv_i32 v2) +{ + TCGv_i32 one = tcg_const_i32(1); + TCGCond c; + + switch (flag) { + case 0x00: + c = TCG_COND_NEVER; + break; + case 0x01: + c = TCG_COND_EQ; + break; + case 0x02: + c = TCG_COND_NE; + break; + case 0x03: + c = TCG_COND_ALWAYS; + break; + default: + g_assert_not_reached(); + break; + } + + tcg_gen_movcond_i32(c, ret, cond, one, v1, v2); + + tcg_temp_free_i32(one); } void e2k_win_commit(DisasContext *dc) { + TCGv_i32 cond = tcg_temp_new_i32(); // Change windowing registers after commit is done. uint32_t ss = dc->bundle.ss; // unsigned int vfdi = (ss & 0x04000000) >> 26; // unsigned int abg = (ss & 0x01800000) >> 23; + unsigned int abp = GET_FIELD(ss, 18, 19); + unsigned int abn = GET_FIELD(ss, 21, 22); + + tcg_gen_trunc_tl_i32(cond, dc->jmp.cond); if (GET_BIT(ss, 16)) { - gen_alc_dec(dc, TCG_COND_EQ); + gen_alc_dec(TCG_COND_EQ, dc->jmp.cond); } if (GET_BIT(ss, 17)) { - gen_alc_dec(dc, TCG_COND_NE); + gen_alc_dec(TCG_COND_NE, dc->jmp.cond); } - if (GET_BIT(ss, 18)) { - gen_abp_inc(dc, TCG_COND_EQ); + if (abp) { + TCGv_i32 t0 = tcg_temp_new_i32(); + + gen_pcur_inc(t0, e2k_cs.br); + gen_movcond_flag_i32(e2k_cs.br, abp, cond, t0, e2k_cs.br); + + tcg_temp_free_i32(t0); } - if (GET_BIT(ss, 19)) { - gen_abp_inc(dc, TCG_COND_NE); - } - if (GET_BIT(ss, 21)) { - gen_abn_inc(dc, TCG_COND_EQ); - } - if (GET_BIT(ss, 22)) { - gen_abn_inc(dc, TCG_COND_NE); + + if (abn) { + TCGv_i32 t0 = tcg_temp_new_i32(); + + gen_rcur_inc(t0, e2k_cs.br); + gen_movcond_flag_i32(e2k_cs.br, abn, cond, t0, e2k_cs.br); + + tcg_temp_free_i32(t0); } + + tcg_temp_free_i32(cond); } -static inline void gen_is_last_iter(TCGv_i64 ret) +static inline void gen_is_last_iter(TCGv ret) { - TCGv_i64 t0 = tcg_temp_new_i64(); - TCGv_i64 t1 = tcg_temp_new_i64(); - TCGv_i64 t2 = tcg_temp_new_i64(); + TCGv t0 = tcg_temp_new(); + TCGv t1 = tcg_temp_new(); + TCGv t2 = tcg_temp_new(); e2k_gen_lcnt(t0); - tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t0, 2); - tcg_gen_extract_i64(t2, e2k_cs.lsr, LSR_VLC_OFF, 1); - tcg_gen_and_i64(ret, t1, t2); + tcg_gen_setcondi_tl(TCG_COND_LTU, t1, t0, 2); + tcg_gen_extract_tl(t2, e2k_cs.lsr, LSR_VLC_OFF, 1); + tcg_gen_and_tl(ret, t1, t2); tcg_temp_free(t2); tcg_temp_free(t1); tcg_temp_free(t0); } -static inline void gen_is_loop_end(TCGv_i64 ret) +static inline void gen_is_loop_end(TCGv ret) { - TCGv_i64 t0 = tcg_temp_new_i64(); - TCGv_i64 t1 = tcg_temp_new_i64(); - TCGv_i64 t2 = tcg_temp_new_i64(); + TCGv t0 = tcg_temp_new(); + TCGv t1 = tcg_temp_new(); + TCGv t2 = tcg_temp_new(); e2k_gen_ecnt(t0); - tcg_gen_setcondi_i64(TCG_COND_EQ, t1, t0, 0); + tcg_gen_setcondi_tl(TCG_COND_EQ, t1, t0, 0); gen_is_last_iter(t2); - tcg_gen_and_i64(ret, t1, t2); + tcg_gen_and_tl(ret, t1, t2); - tcg_temp_free_i64(t2); - tcg_temp_free_i64(t1); - tcg_temp_free_i64(t0); + tcg_temp_free(t2); + tcg_temp_free(t1); + tcg_temp_free(t0); } static void gen_cs0(DisasContext *dc) @@ -324,6 +366,7 @@ static void gen_cs1(DisasContext *dc) abort(); } else { uint32_t lts0 = bundle->lts[0]; + tcg_gen_movi_i32(e2k_cs.wsz, GET_FIELD(lts0, 5, 11)); tcg_gen_movi_i32(e2k_cs.nfx, GET_BIT(lts0, 4)); @@ -334,17 +377,15 @@ static void gen_cs1(DisasContext *dc) } if (setbn) { - unsigned int rcur = (cs1 & 0x0003f000) >> 12; - unsigned int rsz = (cs1 & 0x00000fc0) >> 6; - unsigned int rbs = cs1 & 0x0000003f; - - tcg_gen_movi_i32(e2k_cs.rcur, rcur); - tcg_gen_movi_i32(e2k_cs.rsz, rsz); - tcg_gen_movi_i32(e2k_cs.rbs, rbs); + TCGv_i32 bn = tcg_const_i32(GET_FIELD(cs1, BR_BN_OFF, BR_BN_END)); + tcg_gen_deposit_i32(e2k_cs.br, e2k_cs.br, bn, BR_BN_OFF, BR_BN_LEN); + tcg_temp_free_i32(bn); } if (setbp) { - tcg_gen_movi_i64(e2k_cs.psz, GET_FIELD(cs1, 18, 23)); + TCGv_i32 bp = tcg_const_i32(GET_FIELD(cs1, BR_PSZ_OFF, BR_PSZ_END)); + tcg_gen_deposit_i32(e2k_cs.br, e2k_cs.br, bp, BR_BP_OFF, BR_BP_LEN); + tcg_temp_free_i32(bp); } } else if (opc == SETEI) { /* Verify that CS1.param.sft = CS1.param[27] is equal to zero as required @@ -458,58 +499,52 @@ static void gen_jmp(DisasContext *dc) if (cond_type == 1) { dc->base.is_jmp = STATIC_JUMP; - tcg_gen_movi_i64(dc->jmp.cond, 1); + tcg_gen_movi_tl(dc->jmp.cond, 1); } else { /* TODO: single assign */ - TCGv_i64 cond = tcg_temp_new_i64(); + TCGv cond = tcg_temp_new(); + TCGv preg = tcg_temp_new(); + TCGv loop_end = tcg_temp_new(); + TCGv not_loop_end = tcg_temp_new(); dc->base.is_jmp = DYNAMIC_JUMP; - if (cond_type == 2 || cond_type == 6 || cond_type == 0xf) { - /* if pred is true */ - tcg_gen_mov_i64(cond, e2k_get_preg(dc, psrc)); - } else if (cond_type == 3 || cond_type == 7 || cond_type == 0xe) { - /* if pred is false */ - TCGv_i64 one = tcg_const_i64(1); - TCGv_i64 zero = tcg_const_i64(0); - tcg_gen_movcond_i64(TCG_COND_EQ, cond, - e2k_get_preg(dc, psrc), zero, - one, zero); - tcg_temp_free_i64(zero); - tcg_temp_free_i64(one); + e2k_gen_preg(preg, psrc); + gen_is_loop_end(loop_end); + tcg_gen_setcondi_tl(TCG_COND_NE, not_loop_end, loop_end, 1); + + switch (cond_type) { + case 0x2: + case 0x6: + case 0xf: + tcg_gen_mov_tl(cond, preg); + break; + case 0x3: + case 0x7: + case 0xe: + tcg_gen_setcondi_tl(TCG_COND_NE, cond, preg, 1); + break; + default: + break; } - /* TODO: other kinds of conditions */ - - if (cond_type == 4 || cond_type == 6 || cond_type == 0xe) { - TCGv_i64 is_loop_end = tcg_temp_new_i64(); - - gen_is_loop_end(is_loop_end); - - if (cond_type == 6 || cond_type == 0xe) { - tcg_gen_or_i64(cond, cond, is_loop_end); - } else { - tcg_gen_mov_i64(cond, is_loop_end); - } - - tcg_temp_free_i64(is_loop_end); - } - - if (cond_type == 5 || cond_type == 7 || cond_type == 0xf) { - TCGv_i64 is_loop_end = tcg_temp_new_i64(); - TCGv_i64 t0 = tcg_temp_new_i64(); - - gen_is_loop_end(is_loop_end); - tcg_gen_setcondi_i64(TCG_COND_EQ, t0, is_loop_end, 0); - - if(cond_type == 7 || cond_type == 0xf) { - tcg_gen_and_i64(cond, cond, t0); - } else { - tcg_gen_mov_i64(cond, t0); - } - - tcg_temp_free_i64(t0); - tcg_temp_free_i64(is_loop_end); + switch (cond_type) { + case 0x4: + tcg_gen_mov_tl(cond, loop_end); + break; + case 0x5: + tcg_gen_mov_tl(cond, not_loop_end); + break; + case 0x6: + case 0xe: + tcg_gen_or_tl(cond, cond, loop_end); + break; + case 0x7: + case 0xf: + tcg_gen_and_tl(cond, cond, not_loop_end); + break; + default: + break; } if (cond_type == 8) { @@ -561,9 +596,12 @@ static void gen_jmp(DisasContext *dc) abort(); } - tcg_gen_mov_i64(dc->jmp.cond, cond); + tcg_gen_mov_tl(dc->jmp.cond, cond); - tcg_temp_free_i64(cond); + tcg_temp_free(not_loop_end); + tcg_temp_free(loop_end); + tcg_temp_free(preg); + tcg_temp_free(cond); } /* TODO: check CPU behavior if present ibranch and ctpr is not zero */ @@ -576,12 +614,8 @@ static void gen_jmp(DisasContext *dc) dc->base.is_jmp = DISAS_CALL; return; } - TCGv_i64 t0 = tcg_temp_new_i64(); - tcg_gen_andi_i64(t0, e2k_cs.ctprs[ctpr], GEN_MASK(0, 47)); - tcg_gen_mov_tl(dc->jmp.dest, t0); - - tcg_temp_free_i64(t0); + tcg_gen_andi_tl(dc->jmp.dest, e2k_cs.ctprs[ctpr], GEN_MASK(0, 47)); } } diff --git a/target/e2k/translate/state.c b/target/e2k/translate/state.c index 40b6eb45e7..00e1d73520 100644 --- a/target/e2k/translate/state.c +++ b/target/e2k/translate/state.c @@ -7,15 +7,24 @@ static void gen_preg_offset(TCGv_i64 ret, int reg) { assert(reg < 32); - TCGv_i64 t0 = tcg_temp_new_i64(); - TCGv_i64 t1 = tcg_temp_new_i64(); + TCGv_i32 pcur = tcg_temp_new_i32(); + TCGv_i32 psz = tcg_temp_new_i32(); + TCGv_i32 t0 = tcg_temp_new_i32(); + TCGv_i32 t1 = tcg_temp_new_i32(); + TCGv_i32 t2 = tcg_temp_new_i32(); - tcg_gen_addi_i64(t0, e2k_cs.pcur, reg); - e2k_gen_wrap_i64(t1, t0, e2k_cs.psz); - tcg_gen_shli_i64(ret, t1, 1); + tcg_gen_extract_i32(pcur, e2k_cs.br, BR_PCUR_OFF, BR_PCUR_LEN); + tcg_gen_extract_i32(psz, e2k_cs.br, BR_PSZ_OFF, BR_PSZ_LEN); + tcg_gen_addi_i32(t0, pcur, reg); + e2k_gen_wrap_i32(t1, t0, psz); + tcg_gen_shli_i32(t2, t1, 1); + tcg_gen_extu_i32_i64(ret, t2); - tcg_temp_free_i64(t1); - tcg_temp_free_i64(t0); + tcg_temp_free_i32(t2); + tcg_temp_free_i32(t1); + tcg_temp_free_i32(t0); + tcg_temp_free_i32(psz); + tcg_temp_free_i32(pcur); } static void gen_preg_clear(TCGv_i64 ret, TCGv_i64 offset) @@ -123,16 +132,21 @@ void e2k_gen_store_wreg(int reg, TCGv_i64 val) static inline void gen_breg_start(TCGv_i32 ret) { + TCGv_i32 rbs = tcg_temp_new_i32(); TCGv_i32 t0 = tcg_temp_new_i32(); - tcg_gen_add_i32(t0, e2k_cs.wbs, e2k_cs.rbs); + tcg_gen_extract_i32(rbs, e2k_cs.br, BR_RBS_OFF, BR_RBS_LEN); + tcg_gen_add_i32(t0, e2k_cs.wbs, rbs); tcg_gen_shli_i32(ret, t0, 1); tcg_temp_free_i32(t0); + tcg_temp_free_i32(rbs); } static inline void gen_breg_offset(TCGv_i32 ret, int reg) { + TCGv_i32 rcur = tcg_temp_new_i32(); + TCGv_i32 rsz = tcg_temp_new_i32(); TCGv_i32 t0 = tcg_temp_new_i32(); TCGv_i32 t1 = tcg_temp_new_i32(); TCGv_i32 t2 = tcg_temp_new_i32(); @@ -144,9 +158,11 @@ static inline void gen_breg_offset(TCGv_i32 ret, int reg) /* TODO: exception: reg > (rsz * 2 + 2) */ /* t = (reg + rcur * 2) % (rsz * 2 + 2) */ - tcg_gen_shli_i32(t0, e2k_cs.rcur, 1); + tcg_gen_extract_i32(rcur, e2k_cs.br, BR_RCUR_OFF, BR_RCUR_LEN); + tcg_gen_extract_i32(rsz, e2k_cs.br, BR_RSZ_OFF, BR_RSZ_LEN); + tcg_gen_shli_i32(t0, rcur, 1); tcg_gen_addi_i32(t1, t0, reg); - tcg_gen_addi_i32(t2, e2k_cs.rsz, 1); + tcg_gen_addi_i32(t2, rsz, 1); tcg_gen_shli_i32(t3, t2, 1); e2k_gen_wrap_i32(t4, t1, t3); @@ -167,6 +183,8 @@ static inline void gen_breg_offset(TCGv_i32 ret, int reg) tcg_temp_free_i32(t2); tcg_temp_free_i32(t1); tcg_temp_free_i32(t0); + tcg_temp_free_i32(rsz); + tcg_temp_free_i32(rcur); } static inline void gen_breg_ptr(TCGv_ptr ret, int reg)