target: e2k: Move %br parts to %br.
This commit is contained in:
parent
54feb6fbe3
commit
a5f7f32a8f
|
@ -73,6 +73,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);
|
||||
|
@ -84,9 +101,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) {
|
||||
|
|
|
@ -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 CPUArchState {
|
|||
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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -189,7 +189,7 @@ static target_ulong unpack_bundle(CPUE2KState *env, DisasContext *ctx)
|
|||
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)
|
||||
|
@ -360,18 +360,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;
|
||||
}
|
||||
|
@ -380,8 +380,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,
|
||||
|
@ -425,16 +425,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" },
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue