target: e2k: Move %br parts to %br.

This commit is contained in:
Denis Drakhnia 2020-11-14 11:20:18 +02:00 committed by Denis Drakhnia
parent 54feb6fbe3
commit a5f7f32a8f
9 changed files with 236 additions and 161 deletions

View File

@ -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) {

View File

@ -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;

View File

@ -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) {

View File

@ -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)

View File

@ -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" },

View File

@ -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;

View File

@ -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);

View File

@ -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));
}
}

View File

@ -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)