target: e2k: Restricted loop_mode implementation.

This commit is contained in:
Denis Drakhnia 2020-12-09 00:08:55 +02:00 committed by Denis Drakhnia
parent 0f874d1b0b
commit 1c03415d9e
8 changed files with 249 additions and 167 deletions

View File

@ -186,6 +186,7 @@ typedef enum {
#define LSR_ECNT_END 36
#define LSR_ECNT_LEN (LSR_ECNT_END - LSR_ECNT_OFF + 1)
#define LSR_VLC_OFF 37 /* loop count valid bit */
#define LSR_VLC_BIT (1UL << LSR_VLC_OFF)
#define LSR_OVER_OFF 38 /* loop count overflow */
#define LSR_LDMC_OFF 39 /* loads manual control */
#define LSR_LDOVL_OFF 40 /* load overlap */

View File

@ -311,7 +311,7 @@ static inline void do_branch(DisasContext *ctx, target_ulong pc_next)
if (ctx->ct.is_branch) {
TCGLabel *l0 = gen_new_label();
tcg_gen_brcondi_tl(TCG_COND_NE, e2k_cs.ct_cond, 0, l0);
tcg_gen_brcondi_i32(TCG_COND_NE, e2k_cs.ct_cond, 0, l0);
gen_goto_tb(ctx, TB_EXIT_IDX1, pc_next);
gen_set_label(l0);
}
@ -369,7 +369,7 @@ static void e2k_tr_tb_start(DisasContextBase *db, CPUState *cs)
{
// DisasContext *ctx = container_of(db, DisasContext, base);
tcg_gen_movi_tl(e2k_cs.ct_cond, 0);
tcg_gen_movi_i32(e2k_cs.ct_cond, 0);
}
static void e2k_tr_insn_start(DisasContextBase *db, CPUState *cs)
@ -467,6 +467,7 @@ void e2k_tcg_initialize(void) {
{ &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" },
{ &e2k_cs.ct_cond, offsetof(CPUE2KState, ct_cond), "cond" },
};
static const struct { TCGv_i64 *ptr; int off; const char *name; } r64[] = {
@ -477,7 +478,6 @@ void e2k_tcg_initialize(void) {
static const struct { TCGv *ptr; int off; const char *name; } rtl[] = {
{ &e2k_cs.pc, offsetof(CPUE2KState, ip), "pc" },
{ &e2k_cs.npc, offsetof(CPUE2KState, nip), "npc" },
{ &e2k_cs.ct_cond, offsetof(CPUE2KState, ct_cond), "cond" },
};
unsigned int i;

View File

@ -4,21 +4,6 @@
#include "tcg/tcg-op.h"
#include "exec/translator.h"
/* ibranch disp */
#define DISAS_JUMP_STATIC DISAS_TARGET_0
/* ibranch disp ? cond */
#define DISAS_BRANCH_STATIC DISAS_TARGET_1
/*
* ct %ctprN
* call %ctprN, wbs=M
* */
#define DISAS_JUMP DISAS_TARGET_2
/*
* ct %ctprN ? cond
* call %ctprN, wbs=M ? cond
*/
#define DISAS_BRANCH DISAS_TARGET_3
#define IS_BASED(i) (((i) & 0x80) == 0)
#define IS_REGULAR(i) (((i) & 0xc0) == 0x80)
#define IS_IMM5(i) (((i) & 0xe0) == 0xc0)
@ -52,7 +37,7 @@ typedef struct CPUE2KStateTCG {
TCGv pc;
TCGv npc;
TCGv_i64 ctprs[3];
TCGv ct_cond;
TCGv_i32 ct_cond;
TCGv_i32 is_bp; /* breakpoint flag */
TCGv_i64 lsr;
TCGv_i64 regs[E2K_REG_COUNT];
@ -186,6 +171,9 @@ typedef struct DisasContext {
int jump_ctpr;
int mmuidx;
uint8_t mas[6];
bool loop_mode;
TCGv_i32 is_prologue;
TCGv_i32 is_epilogue;
int version;
@ -312,23 +300,67 @@ static inline TCGv e2k_get_temp(DisasContext *dc)
return dc->ttl[dc->ttl_len++] = tcg_temp_local_new();
}
static inline void e2k_gen_lcnt(TCGv_i64 ret)
static inline void e2k_gen_lcnt_i64(TCGv_i64 ret)
{
tcg_gen_andi_i64(ret, e2k_cs.lsr, (1UL << 32) - 1);
}
static inline void e2k_gen_ecnt(TCGv_i64 ret)
static inline void e2k_gen_lcnt_i32(TCGv_i32 ret)
{
TCGv_i64 t0 = tcg_temp_new_i64();
e2k_gen_lcnt_i64(t0);
tcg_gen_extrl_i64_i32(ret, t0);
tcg_temp_free_i64(t0);
}
static inline void e2k_gen_lcnt_set_i32(TCGv_i32 value)
{
TCGv_i64 t0 = tcg_temp_new_i64();
tcg_gen_extu_i32_i64(t0, value);
tcg_gen_deposit_i64(e2k_cs.lsr, e2k_cs.lsr, t0, LSR_LCNT_OFF, LSR_LCNT_LEN);
tcg_temp_free_i64(t0);
}
static inline void e2k_gen_ecnt_i64(TCGv_i64 ret)
{
tcg_gen_extract_i64(ret, e2k_cs.lsr, LSR_ECNT_OFF, LSR_ECNT_LEN);
}
static inline void e2k_gen_pcnt(TCGv_i32 ret)
static inline void e2k_gen_ecnt_i32(TCGv_i32 ret)
{
TCGv_i64 t0 = tcg_temp_new_i64();
e2k_gen_ecnt_i64(t0);
tcg_gen_extrl_i64_i32(ret, t0);
tcg_temp_free_i64(t0);
}
static inline void e2k_gen_ecnt_set_i32(TCGv_i32 value)
{
TCGv_i64 t0 = tcg_temp_new_i64();
tcg_gen_extu_i32_i64(t0, value);
tcg_gen_deposit_i64(e2k_cs.lsr, e2k_cs.lsr, t0, LSR_ECNT_OFF, LSR_ECNT_LEN);
tcg_temp_free_i64(t0);
}
static inline void e2k_gen_pcnt_i32(TCGv_i32 ret)
{
TCGv_i64 t0 = tcg_temp_new_i64();
tcg_gen_extract_i64(t0, e2k_cs.lsr, LSR_PCNT_OFF, LSR_PCNT_LEN);
tcg_gen_extrl_i64_i32(ret, t0);
tcg_temp_free_i64(t0);
}
static inline void e2k_gen_pcnt_set_i32(TCGv_i32 value)
{
TCGv_i64 t0 = tcg_temp_new_i64();
tcg_gen_extu_i32_i64(t0, value);
tcg_gen_deposit_i64(e2k_cs.lsr, e2k_cs.lsr, t0, LSR_PCNT_OFF, LSR_PCNT_LEN);
tcg_temp_free_i64(t0);
}
@ -397,7 +429,8 @@ void e2k_gen_reg_read_i32(TCGv_i32 ret, TCGv_i32 idx);
void e2k_gen_reg_write_i64(TCGv_i64 value, TCGv_i32 idx);
void e2k_gen_reg_write_i32(TCGv_i32 value, TCGv_i32 idx);
void e2k_gen_preg(TCGv_i64 ret, int reg);
void e2k_gen_preg_i64(TCGv_i64 ret, int reg);
void e2k_gen_preg_i32(TCGv_i32 ret, int reg);
TCGv_i64 e2k_get_preg(DisasContext *dc, int reg);
void e2k_gen_cond_i32(DisasContext *ctx, TCGv_i32 ret, uint8_t psrc);
@ -412,6 +445,42 @@ static inline void e2k_gen_cond_i64(DisasContext *ctx, TCGv_i64 ret,
tcg_temp_free_i32(t0);
}
static inline void e2k_gen_is_last_iter(TCGv_i32 ret)
{
TCGv_i32 t0 = tcg_temp_new_i32();
TCGv_i32 t1 = tcg_temp_new_i32();
TCGv_i64 t2 = tcg_temp_new_i64();
TCGv_i32 t3 = tcg_temp_new_i32();
e2k_gen_lcnt_i32(t0);
tcg_gen_setcondi_i32(TCG_COND_LTU, t1, t0, 2);
tcg_gen_andi_i64(t2, e2k_cs.lsr, LSR_VLC_BIT);
tcg_gen_setcondi_i64(TCG_COND_NE, t2, t2, 0);
tcg_gen_extrl_i64_i32(t3, t2);
tcg_gen_and_i32(ret, t1, t3);
tcg_temp_free_i32(t3);
tcg_temp_free_i64(t2);
tcg_temp_free_i32(t1);
tcg_temp_free_i32(t0);
}
static inline void e2k_gen_is_loop_end_i32(TCGv_i32 ret)
{
TCGv_i32 t0 = tcg_temp_new_i32();
TCGv_i32 t1 = tcg_temp_new_i32();
TCGv_i32 t2 = tcg_temp_new_i32();
e2k_gen_ecnt_i32(t0);
tcg_gen_setcondi_i32(TCG_COND_EQ, t1, t0, 0);
e2k_gen_is_last_iter(t2);
tcg_gen_and_i32(ret, t1, t2);
tcg_temp_free_i32(t2);
tcg_temp_free_i32(t1);
tcg_temp_free_i32(t0);
}
void e2k_control_execute(DisasContext *ctx);
void e2k_control_window_change(DisasContext *ctx);
void e2k_stubs_commit(DisasContext *ctx);

View File

@ -97,7 +97,8 @@ static void gen_mova(DisasContext *ctx, Instr *instr)
TCGv t5 = tcg_temp_new();
ctx->aau_am[instr->chan] = instr->am ? instr->area : -1;
// TODO: check ind
// TODO: check ind has proper alignment
// TODO: check ind is less than mrng
gen_mova_ptr(t5, instr);
switch(instr->opc) {
@ -110,9 +111,11 @@ static void gen_mova(DisasContext *ctx, Instr *instr)
gen_mova_i64(ctx, instr, t5);
break;
case 5: /* movaq */
qemu_log_mask(LOG_UNIMP, "0x%lx: movaq is not implemented\n", ctx->pc);
abort();
break;
case 7: /* movaqp */
qemu_log_mask(LOG_UNIMP, "0x%lx: movaqp is not implemented\n", ctx->pc);
abort();
break;
default:

View File

@ -1506,8 +1506,13 @@ static void gen_aad_ptr(DisasContext *ctx, TCGv ret, Instr *instr)
static void gen_staa_i64(DisasContext *ctx, Instr *instr)
{
uint8_t mas = ctx->mas[instr->chan];
TCGLabel *l0 = gen_new_label();
Src64 s4 = get_src4_i64(ctx, instr->chan);
if (ctx->loop_mode) {
tcg_gen_brcondi_i32(TCG_COND_EQ, ctx->is_prologue, 1, l0);
}
gen_tag_check(ctx, instr->sm, s4.tag);
if (mas == 0x3f) {
/* aaurwd */
@ -1545,13 +1550,20 @@ static void gen_staa_i64(DisasContext *ctx, Instr *instr)
gen_aasti_incr(ctx, instr, 8);
}
}
gen_set_label(l0);
}
static void gen_staa_i32(DisasContext *ctx, Instr *instr, MemOp memop)
{
uint8_t mas = ctx->mas[instr->chan];
TCGLabel *l0 = gen_new_label();
Src32 s4 = get_src4_i32(ctx, instr->chan);
if (ctx->loop_mode) {
tcg_gen_brcondi_i32(TCG_COND_EQ, ctx->is_prologue, 1, l0);
}
gen_tag_check(ctx, instr->sm, s4.tag);
if (mas == 0x3f) {
/* aaurw */
@ -1608,6 +1620,8 @@ static void gen_staa_i32(DisasContext *ctx, Instr *instr, MemOp memop)
gen_aasti_incr(ctx, instr, len);
}
}
gen_set_label(l0);
}
static void gen_alopf1_i64(DisasContext *ctx, int chan,

View File

@ -3,97 +3,26 @@
#include "exec/log.h"
#include "translate.h"
static inline void gen_lcnt_dec(TCGv_i64 ret, TCGv_i64 lsr)
static inline TCGCond cond_from_advance(int advance)
{
TCGv_i32 zero = tcg_const_i32(0);
TCGv_i32 lcnt = 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 t4 = tcg_temp_new_i32();
TCGv_i32 t5 = tcg_temp_new_i32();
tcg_gen_extrl_i64_i32(lcnt, lsr);
tcg_gen_subi_i32(t0, lcnt, 1);
tcg_gen_movcond_i32(TCG_COND_EQ, t1, lcnt, zero, zero, t0);
/* overflow bit */
tcg_gen_extrh_i64_i32(t2, lsr);
tcg_gen_setcondi_i32(TCG_COND_EQ, t3, lcnt, 1);
tcg_gen_shli_i32(t4, t3, LSR_OVER_OFF - 32);
tcg_gen_or_i32(t5, t2, t4);
tcg_gen_concat_i32_i64(ret, t1, t5);
tcg_temp_free_i32(t5);
tcg_temp_free_i32(t4);
tcg_temp_free_i32(t3);
tcg_temp_free_i32(t2);
tcg_temp_free_i32(t1);
tcg_temp_free_i32(t0);
tcg_temp_free_i32(lcnt);
tcg_temp_free_i32(zero);
switch (advance) {
case 0x01: return TCG_COND_EQ;
case 0x02: return TCG_COND_NE;
case 0x03: return TCG_COND_ALWAYS;
default: return TCG_COND_NEVER;
}
}
static 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;
}
TCGCond c = cond_from_advance(flag);
tcg_gen_movcond_i32(c, ret, cond, one, v1, v2);
tcg_temp_free_i32(one);
}
static inline void gen_movcond_flag_i64(TCGv_i64 ret, int flag, TCGv_i64 cond,
TCGv_i64 v1, TCGv_i64 v2)
{
TCGv_i64 one = tcg_const_i64(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_i64(c, ret, cond, one, v1, v2);
tcg_temp_free_i64(one);
}
static inline void gen_dec_wrap(TCGv_i32 ret, TCGv_i32 cur, int n,
TCGv_i32 size)
{
@ -112,18 +41,92 @@ static inline void gen_cur_dec(DisasContext *ctx, TCGv_i32 ret, int cond,
{
TCGLabel *l0 = gen_new_label();
TCGv_i32 t0 = tcg_temp_new_i32();
TCGv_i32 t1 = tcg_temp_new_i32();
tcg_gen_brcondi_i32(TCG_COND_EQ, size, 0, l0);
tcg_gen_trunc_tl_i32(t0, e2k_cs.ct_cond);
gen_dec_wrap(t1, cur, n, size);
gen_movcond_flag_i32(ret, cond, t0, t1, cur);
gen_dec_wrap(t0, cur, n, size);
gen_movcond_flag_i32(ret, cond, e2k_cs.ct_cond, t0, cur);
gen_set_label(l0);
tcg_temp_free_i32(t0);
}
static void gen_advance_pcnt(void)
{
TCGLabel *l0 = gen_new_label();
TCGv_i32 t0 = tcg_temp_local_new_i32();
TCGv_i32 t1 = tcg_temp_new_i32();
e2k_gen_pcnt_i32(t0);
tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l0);
tcg_gen_subi_i32(t1, t0, 1);
e2k_gen_pcnt_set_i32(t1);
gen_set_label(l0);
tcg_temp_free_i32(t1);
tcg_temp_free_i32(t0);
}
static inline void gen_lcnt_overflow(TCGv_i32 lcnt)
{
TCGv_i64 t0 = tcg_temp_new_i64();
TCGv_i64 t1 = tcg_temp_new_i64();
tcg_gen_extu_i32_i64(t0, lcnt);
tcg_gen_setcondi_i64(TCG_COND_EQ, t1, t0, 0);
tcg_gen_shli_i64(t1, t1, LSR_OVER_OFF);
tcg_gen_or_i64(e2k_cs.lsr, e2k_cs.lsr, t1);
tcg_temp_free_i64(t1);
tcg_temp_free_i64(t0);
}
static void gen_advance_lcnt(TCGv_i32 ret)
{
TCGLabel *l0 = gen_new_label();
TCGv_i32 t0 = tcg_temp_local_new_i32();
e2k_gen_lcnt_i32(t0);
tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l0);
tcg_gen_subi_i32(t0, t0, 1);
e2k_gen_lcnt_set_i32(t0);
gen_set_label(l0);
gen_lcnt_overflow(t0);
tcg_gen_mov_i32(ret, t0);
tcg_temp_free_i32(t0);
}
static void gen_advance_ecnt(void)
{
TCGLabel *l0 = gen_new_label();
TCGv_i32 t0 = tcg_temp_local_new_i32();
TCGv_i32 t1 = tcg_temp_new_i32();
e2k_gen_ecnt_i32(t0);
tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l0);
tcg_gen_subi_i32(t1, t0, 1);
e2k_gen_ecnt_set_i32(t1);
gen_set_label(l0);
tcg_temp_free_i32(t1);
tcg_temp_free_i32(t0);
}
static void gen_advance_loop_counters(void)
{
TCGLabel *l0 = gen_new_label();
TCGv_i32 t0 = tcg_temp_new_i32();
gen_advance_pcnt();
gen_advance_lcnt(t0);
tcg_gen_brcondi_i32(TCG_COND_NE, t0, 0, l0);
gen_advance_ecnt();
gen_set_label(l0);
tcg_temp_free_i32(t0);
}
void e2k_stubs_commit(DisasContext *ctx)
{
uint32_t ss = ctx->bundle.ss;
@ -135,11 +138,12 @@ void e2k_stubs_commit(DisasContext *ctx)
int abg = GET_FIELD(ss, 23, 2);
if (alc) {
TCGv_i64 t0 = tcg_temp_new_i64();
TCGLabel *l0 = gen_new_label();
TCGCond cond = cond_from_advance(alc);
gen_lcnt_dec(t0, e2k_cs.lsr);
gen_movcond_flag_i64(e2k_cs.lsr, alc, e2k_cs.ct_cond, t0, e2k_cs.lsr);
tcg_temp_free_i64(t0);
tcg_gen_brcondi_i32(tcg_invert_cond(cond), e2k_cs.ct_cond, 1, l0);
gen_advance_loop_counters();
gen_set_label(l0);
}
if (abp) {
@ -170,38 +174,6 @@ void e2k_stubs_commit(DisasContext *ctx)
}
}
static inline void gen_is_last_iter(TCGv ret)
{
TCGv t0 = tcg_temp_new();
TCGv t1 = tcg_temp_new();
TCGv t2 = tcg_temp_new();
e2k_gen_lcnt(t0);
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 ret)
{
TCGv t0 = tcg_temp_new();
TCGv t1 = tcg_temp_new();
TCGv t2 = tcg_temp_new();
e2k_gen_ecnt(t0);
tcg_gen_setcondi_tl(TCG_COND_EQ, t1, t0, 0);
gen_is_last_iter(t2);
tcg_gen_and_tl(ret, t1, t2);
tcg_temp_free(t2);
tcg_temp_free(t1);
tcg_temp_free(t0);
}
static void gen_cs0(DisasContext *dc)
{
typedef enum {
@ -469,30 +441,28 @@ static void gen_jmp(DisasContext *dc)
}
if (cond_type == 1) {
tcg_gen_movi_tl(e2k_cs.ct_cond, 1);
tcg_gen_movi_i32(e2k_cs.ct_cond, 1);
} else if (cond_type > 1) {
TCGv preg = tcg_temp_new();
TCGv loop_end = tcg_temp_new();
TCGv not_loop_end = tcg_temp_new();
TCGv cond = e2k_cs.ct_cond;
TCGv_i64 t0 = tcg_temp_new_i64();
TCGv_i32 preg = tcg_temp_new_i32();
TCGv_i32 loop_end = tcg_temp_new_i32();
TCGv_i32 not_loop_end = tcg_temp_new_i32();
TCGv_i32 cond = e2k_cs.ct_cond;
dc->ct.is_branch = true;
e2k_gen_preg(t0, psrc);
tcg_gen_trunc_i64_tl(preg, t0);
gen_is_loop_end(loop_end);
tcg_gen_setcondi_tl(TCG_COND_NE, not_loop_end, loop_end, 1);
e2k_gen_preg_i32(preg, psrc);
e2k_gen_is_loop_end_i32(loop_end);
tcg_gen_setcondi_i32(TCG_COND_NE, not_loop_end, loop_end, 1);
switch (cond_type) {
case 0x2:
case 0x6:
case 0xf:
tcg_gen_mov_tl(cond, preg);
tcg_gen_mov_i32(cond, preg);
break;
case 0x3:
case 0x7:
case 0xe:
tcg_gen_setcondi_tl(TCG_COND_NE, cond, preg, 1);
tcg_gen_setcondi_i32(TCG_COND_NE, cond, preg, 1);
break;
default:
break;
@ -500,24 +470,25 @@ static void gen_jmp(DisasContext *dc)
switch (cond_type) {
case 0x4:
tcg_gen_mov_tl(cond, loop_end);
tcg_gen_mov_i32(cond, loop_end);
break;
case 0x5:
tcg_gen_mov_tl(cond, not_loop_end);
tcg_gen_mov_i32(cond, not_loop_end);
break;
case 0x6:
case 0xe:
tcg_gen_or_tl(cond, cond, loop_end);
tcg_gen_or_i32(cond, cond, loop_end);
break;
case 0x7:
case 0xf:
tcg_gen_and_tl(cond, cond, not_loop_end);
tcg_gen_and_i32(cond, cond, not_loop_end);
break;
default:
break;
}
if (cond_type == 8) {
qemu_log_mask(LOG_UNIMP, "0x%lx: ct cond is not implemented!\n", dc->pc);
// %MLOCK
/* It's not clearly said in C.17.1.2 of iset-vX.single if the uppermost
fourth bit in `psrc' has any meaning at all. */
@ -536,6 +507,7 @@ static void gen_jmp(DisasContext *dc)
/* `lock_cond || pl_cond' control transfer conditions. */
if (cond_type == 9) {
qemu_log_mask(LOG_UNIMP, "0x%lx: ct cond is not implemented!\n", dc->pc);
unsigned int type = (psrc & 0x18) >> 3;
if (type == 0) {
// static const int cmp_num_to_alc[] = {0, 1, 3, 4};
@ -567,10 +539,9 @@ static void gen_jmp(DisasContext *dc)
}
tcg_temp_free_i64(t0);
tcg_temp_free(not_loop_end);
tcg_temp_free(loop_end);
tcg_temp_free(preg);
tcg_temp_free_i32(not_loop_end);
tcg_temp_free_i32(loop_end);
tcg_temp_free_i32(preg);
}
}
@ -647,6 +618,21 @@ void e2k_control_execute(DisasContext *ctx)
{
ctx->ct.type = CT_NONE;
ctx->loop_mode = (ctx->bundle.hs & (1 << 10)) != 0;
if (ctx->loop_mode) {
TCGv_i32 t0 = tcg_temp_new_i32();
ctx->is_prologue = e2k_get_temp_i32(ctx);
e2k_gen_pcnt_i32(t0);
tcg_gen_setcondi_i32(TCG_COND_NE, ctx->is_prologue, t0, 0);
ctx->is_epilogue = e2k_get_temp_i32(ctx);
e2k_gen_lcnt_i32(t0);
tcg_gen_setcondi_i32(TCG_COND_EQ, ctx->is_epilogue, t0, 0);
tcg_temp_free_i32(t0);
}
if (ctx->bundle.ss_present) {
gen_jmp(ctx);
}

View File

@ -35,7 +35,7 @@ void e2k_gen_cond_i32(DisasContext *ctx, TCGv_i32 ret, uint8_t psrc)
int reg = GET_FIELD(psrc, 0, 5);
TCGv_i64 t0 = tcg_temp_new_i64();
e2k_gen_preg(t0, reg);
e2k_gen_preg_i64(t0, reg);
tcg_gen_extrl_i64_i32(ret, t0);
tcg_temp_free_i64(t0);
@ -161,7 +161,7 @@ void e2k_plu_execute(DisasContext *ctx)
TCGv_i64 t0 = tcg_temp_new_i64();
TCGv_i32 t1 = tcg_temp_new_i32();
e2k_gen_preg(t0, pdst);
e2k_gen_preg_i64(t0, pdst);
tcg_gen_extrl_i64_i32(t1, t0);
tcg_gen_movcond_i32(TCG_COND_EQ, ctx->pl_results[i].value,
p0, one, p1, t1);

View File

@ -54,7 +54,7 @@ static void gen_preg_clear(TCGv_i64 ret, TCGv_i64 offset)
tcg_temp_free_i64(t0);
}
void e2k_gen_preg(TCGv_i64 ret, int reg)
void e2k_gen_preg_i64(TCGv_i64 ret, int reg)
{
TCGv_i64 one = tcg_const_i64(1);
TCGv_i64 t0 = tcg_temp_new_i64();
@ -72,10 +72,19 @@ void e2k_gen_preg(TCGv_i64 ret, int reg)
tcg_temp_free_i64(one);
}
void e2k_gen_preg_i32(TCGv_i32 ret, int reg)
{
TCGv_i64 t0 = tcg_temp_new_i64();
e2k_gen_preg_i64(t0, reg);
tcg_gen_extrl_i64_i32(ret, t0);
tcg_temp_free_i64(t0);
}
TCGv_i64 e2k_get_preg(DisasContext *dc, int reg)
{
TCGv_i64 ret = e2k_get_temp_i64(dc);
e2k_gen_preg(ret, reg);
e2k_gen_preg_i64(ret, reg);
return ret;
}