target: e2k: Add basic syscall support.
This commit is contained in:
parent
779fc80db4
commit
3e3508f9bd
|
@ -39,7 +39,7 @@ void cpu_loop(CPUE2KState *env)
|
||||||
switch (trapnr) {
|
switch (trapnr) {
|
||||||
case E2K_EXCP_SYSCALL: {
|
case E2K_EXCP_SYSCALL: {
|
||||||
/* TODO: wrap register indices */
|
/* TODO: wrap register indices */
|
||||||
uint64_t *regs = &env->wregs[env->wbs * 2];
|
uint64_t *regs = &env->wregs[env->wbs + env->syscall_wbs];
|
||||||
abi_ulong ret = do_syscall(env, regs[0],
|
abi_ulong ret = do_syscall(env, regs[0],
|
||||||
regs[1], regs[2], regs[3], regs[4],
|
regs[1], regs[2], regs[3], regs[4],
|
||||||
regs[5], regs[6], regs[7], regs[8]);
|
regs[5], regs[6], regs[7], regs[8]);
|
||||||
|
@ -62,5 +62,4 @@ void cpu_loop(CPUE2KState *env)
|
||||||
void target_cpu_copy_regs(CPUE2KState *env, struct target_pt_regs *regs)
|
void target_cpu_copy_regs(CPUE2KState *env, struct target_pt_regs *regs)
|
||||||
{
|
{
|
||||||
env->ip = regs->ip;
|
env->ip = regs->ip;
|
||||||
// TODO
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,8 @@ void e2k_tcg_initialize(void);
|
||||||
#define REG_SIZE (sizeof(target_ulong))
|
#define REG_SIZE (sizeof(target_ulong))
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
E2K_EXCP_SYSCALL = 0x01,
|
E2K_EXCP_UNIMPL = 0x01,
|
||||||
|
E2K_EXCP_SYSCALL = 0x02,
|
||||||
} Exception;
|
} Exception;
|
||||||
|
|
||||||
struct e2k_def_t {
|
struct e2k_def_t {
|
||||||
|
@ -29,14 +30,15 @@ typedef struct {
|
||||||
target_ulong wregs[WREGS_SIZE]; // window regs
|
target_ulong wregs[WREGS_SIZE]; // window regs
|
||||||
target_ulong *win_ptr;
|
target_ulong *win_ptr;
|
||||||
uint64_t pregs;
|
uint64_t pregs;
|
||||||
uint32_t wbs; // window regs offset (* 2)
|
uint32_t wbs; // Real window regs offset, in bundle it comes divided by 2
|
||||||
uint32_t wsz; // window regs size (* 2)
|
uint32_t wsz; // Real window regs size, in bundle it comes divided by 2
|
||||||
uint32_t nfx; // TODO
|
uint32_t nfx; // TODO
|
||||||
uint32_t dbl; // TODO
|
uint32_t dbl; // TODO
|
||||||
uint32_t rbs; // based regs offset (* 2)
|
uint32_t rbs; // Real based regs offset, in bundle it comes divided by 2
|
||||||
uint32_t rsz; // based regs window size (* 2 + 2)
|
uint32_t rsz; // Real based regs size, in bundle it comes divided by 2 minus 2
|
||||||
uint32_t rcur; // based regs current index (* 2)
|
uint32_t rcur; // Real based regs current index, in bundle it comes divided by 2
|
||||||
uint32_t psz; // pred regs window size
|
uint32_t psz; // pred regs window size
|
||||||
|
uint32_t syscall_wbs;
|
||||||
|
|
||||||
/* control registers */
|
/* control registers */
|
||||||
target_ulong ctprs[3]; // Control Transfer Preparation Register (CTPR)
|
target_ulong ctprs[3]; // Control Transfer Preparation Register (CTPR)
|
||||||
|
|
|
@ -13,13 +13,16 @@ void helper_raise_exception(CPUE2KState *env, int tt)
|
||||||
cpu_loop_exit(cs);
|
cpu_loop_exit(cs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void helper_check_syscall_ctpr(CPUE2KState *env, uint64_t ctpr)
|
void helper_call(CPUE2KState *env, uint64_t ctpr, uint64_t cond)
|
||||||
{
|
{
|
||||||
int tag = GET_FIELD(ctpr, CTPR_TAG_OFF, CTPR_TAG_END);
|
int tag = GET_FIELD(ctpr, CTPR_TAG_OFF, CTPR_TAG_END);
|
||||||
if (tag == CTPR_TAG_SDISP) {
|
if (tag == CTPR_TAG_SDISP && cond) {
|
||||||
CPUState *cs = env_cpu(env);
|
CPUState *cs = env_cpu(env);
|
||||||
|
|
||||||
cs->exception_index = E2K_EXCP_SYSCALL;
|
cs->exception_index = E2K_EXCP_SYSCALL;
|
||||||
cpu_loop_exit(cs);
|
cpu_loop_exit(cs);
|
||||||
|
} else {
|
||||||
|
/* TODO: call */
|
||||||
|
abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// include/exec/helper-proto.h needs this file
|
// include/exec/helper-proto.h needs this file
|
||||||
|
|
||||||
DEF_HELPER_2(raise_exception, noreturn, env, int)
|
DEF_HELPER_2(raise_exception, noreturn, env, int)
|
||||||
DEF_HELPER_2(check_syscall_ctpr, void, env, i64)
|
DEF_HELPER_3(call, void, env, i64, i64)
|
||||||
|
|
|
@ -188,6 +188,7 @@ static target_ulong unpack_bundle(CPUE2KState *env,
|
||||||
static inline void save_state(DisasContext *dc)
|
static inline void save_state(DisasContext *dc)
|
||||||
{
|
{
|
||||||
tcg_gen_movi_tl(e2k_cs.pc, dc->pc);
|
tcg_gen_movi_tl(e2k_cs.pc, dc->pc);
|
||||||
|
tcg_gen_movi_tl(e2k_cs.pc, dc->npc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2k_gen_exception(DisasContext *dc, int which)
|
void e2k_gen_exception(DisasContext *dc, int which)
|
||||||
|
@ -233,7 +234,7 @@ static void e2k_tr_translate_insn(DisasContextBase *db, CPUState *cs)
|
||||||
dc->pc = dc->base.pc_next;
|
dc->pc = dc->base.pc_next;
|
||||||
unsigned int bundle_len = unpack_bundle(env, dc->pc, bundle);
|
unsigned int bundle_len = unpack_bundle(env, dc->pc, bundle);
|
||||||
/* TODO: exception, check bundle_len */
|
/* TODO: exception, check bundle_len */
|
||||||
dc->base.pc_next = dc->pc + bundle_len;
|
dc->base.pc_next = dc->npc = dc->pc + bundle_len;
|
||||||
|
|
||||||
e2k_alc_gen(dc);
|
e2k_alc_gen(dc);
|
||||||
e2k_control_gen(dc);
|
e2k_control_gen(dc);
|
||||||
|
@ -259,6 +260,7 @@ static void e2k_tr_tb_start(DisasContextBase *db, CPUState *cs)
|
||||||
{
|
{
|
||||||
DisasContext *dc = container_of(db, DisasContext, base);
|
DisasContext *dc = container_of(db, DisasContext, base);
|
||||||
|
|
||||||
|
dc->is_call = false;
|
||||||
dc->jmp.dest = tcg_const_i64(0);
|
dc->jmp.dest = tcg_const_i64(0);
|
||||||
dc->jmp.cond = tcg_const_i64(0);
|
dc->jmp.cond = tcg_const_i64(0);
|
||||||
}
|
}
|
||||||
|
@ -266,29 +268,36 @@ static void e2k_tr_tb_start(DisasContextBase *db, CPUState *cs)
|
||||||
static void e2k_tr_tb_stop(DisasContextBase *db, CPUState *cs)
|
static void e2k_tr_tb_stop(DisasContextBase *db, CPUState *cs)
|
||||||
{
|
{
|
||||||
DisasContext *dc = container_of(db, DisasContext, base);
|
DisasContext *dc = container_of(db, DisasContext, base);
|
||||||
E2KCPU *cpu = E2K_CPU(cs);
|
|
||||||
// CPUE2KState *env = &cpu->env;
|
|
||||||
|
|
||||||
/* Control transfer */
|
/* Control transfer */
|
||||||
switch(dc->base.is_jmp) {
|
switch(dc->base.is_jmp) {
|
||||||
case DISAS_NEXT:
|
case DISAS_NEXT:
|
||||||
case DISAS_TOO_MANY:
|
case DISAS_TOO_MANY:
|
||||||
break;
|
break;
|
||||||
case DISAS_NORETURN:
|
case DISAS_CALL: {
|
||||||
/* exception */
|
|
||||||
tcg_gen_movi_tl(e2k_cs.pc, dc->pc);
|
tcg_gen_movi_tl(e2k_cs.pc, dc->pc);
|
||||||
|
tcg_gen_movi_tl(e2k_cs.pc, dc->npc);
|
||||||
|
gen_helper_call(cpu_env, e2k_cs.ctprs[dc->call_ctpr], dc->jmp.cond);
|
||||||
tcg_gen_exit_tb(NULL, 0);
|
tcg_gen_exit_tb(NULL, 0);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
case DISAS_NORETURN: {
|
||||||
|
/* exception */
|
||||||
|
tcg_gen_exit_tb(NULL, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case STATIC_JUMP:
|
case STATIC_JUMP:
|
||||||
tcg_gen_mov_i64(e2k_cs.pc, dc->jmp.dest);
|
tcg_gen_mov_i64(e2k_cs.pc, dc->jmp.dest);
|
||||||
tcg_gen_exit_tb(NULL, 0);
|
tcg_gen_exit_tb(NULL, 0);
|
||||||
break;
|
break;
|
||||||
case DYNAMIC_JUMP: {
|
case DYNAMIC_JUMP: {
|
||||||
TCGv_i64 one = tcg_const_i64(1);
|
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,
|
tcg_gen_movcond_i64(TCG_COND_EQ, e2k_cs.pc,
|
||||||
dc->jmp.cond, one,
|
dc->jmp.cond, one,
|
||||||
dc->jmp.dest, e2k_cs.pc
|
dc->jmp.dest, npc
|
||||||
);
|
);
|
||||||
|
tcg_temp_free_i64(npc);
|
||||||
tcg_temp_free_i64(one);
|
tcg_temp_free_i64(one);
|
||||||
tcg_gen_exit_tb(NULL, 0);
|
tcg_gen_exit_tb(NULL, 0);
|
||||||
break;
|
break;
|
||||||
|
@ -347,6 +356,7 @@ void e2k_tcg_initialize(void) {
|
||||||
{ &e2k_cs.rsz, offsetof(CPUE2KState, rsz), "rsz" },
|
{ &e2k_cs.rsz, offsetof(CPUE2KState, rsz), "rsz" },
|
||||||
{ &e2k_cs.rcur, offsetof(CPUE2KState, rcur), "rcur" },
|
{ &e2k_cs.rcur, offsetof(CPUE2KState, rcur), "rcur" },
|
||||||
{ &e2k_cs.psz, offsetof(CPUE2KState, psz), "psz" },
|
{ &e2k_cs.psz, offsetof(CPUE2KState, psz), "psz" },
|
||||||
|
{ &e2k_cs.syscall_wbs, offsetof(CPUE2KState, syscall_wbs), "syscall_wbs" },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct { TCGv_i64 *ptr; int off; const char *name; } r64[] = {
|
static const struct { TCGv_i64 *ptr; int off; const char *name; } r64[] = {
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#define STATIC_JUMP DISAS_TARGET_0
|
#define STATIC_JUMP DISAS_TARGET_0
|
||||||
#define DYNAMIC_JUMP DISAS_TARGET_1
|
#define DYNAMIC_JUMP DISAS_TARGET_1
|
||||||
|
#define DISAS_CALL DISAS_TARGET_2
|
||||||
|
|
||||||
#define GEN_MASK(type, start, end) \
|
#define GEN_MASK(type, start, end) \
|
||||||
((((type) 1 << ((end) - (start) + 1)) - 1) << start)
|
((((type) 1 << ((end) - (start) + 1)) - 1) << start)
|
||||||
|
@ -68,6 +69,7 @@ typedef struct CPUE2KStateTCG {
|
||||||
TCGv_i32 rsz;
|
TCGv_i32 rsz;
|
||||||
TCGv_i32 rcur;
|
TCGv_i32 rcur;
|
||||||
TCGv_i32 psz;
|
TCGv_i32 psz;
|
||||||
|
TCGv_i32 syscall_wbs;
|
||||||
TCGv_ptr win_ptr;
|
TCGv_ptr win_ptr;
|
||||||
TCGv_i64 wregs[WREGS_SIZE];
|
TCGv_i64 wregs[WREGS_SIZE];
|
||||||
TCGv_i64 gregs[32];
|
TCGv_i64 gregs[32];
|
||||||
|
@ -121,12 +123,15 @@ typedef struct DisasContext {
|
||||||
DisasContextBase base;
|
DisasContextBase base;
|
||||||
UnpackedBundle bundle;
|
UnpackedBundle bundle;
|
||||||
target_ulong pc;
|
target_ulong pc;
|
||||||
|
target_ulong npc;
|
||||||
|
bool is_call;
|
||||||
|
int call_ctpr;
|
||||||
|
|
||||||
int version;
|
int version;
|
||||||
|
|
||||||
// Temporary values.
|
// Temporary values.
|
||||||
TCGv_i32 t32[16];
|
TCGv_i32 t32[16];
|
||||||
TCGv_i64 t64[16];
|
TCGv_i64 t64[32];
|
||||||
TCGv ttl[8];
|
TCGv ttl[8];
|
||||||
// Allocated temporary values count.
|
// Allocated temporary values count.
|
||||||
int t32_len;
|
int t32_len;
|
||||||
|
|
|
@ -262,7 +262,7 @@ static void gen_channel(DisasContext *dc, int chan)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x40: // TODO: udivs used as temporary UD
|
case 0x40: // TODO: udivs used as temporary UD
|
||||||
e2k_gen_exception(dc, 1);
|
e2k_gen_exception(dc, E2K_EXCP_UNIMPL);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
qemu_log_mask(LOG_UNIMP, "gen_alc: undefined instruction 0x%x %s\n", opc, sm ? "(speculative)" : "");
|
qemu_log_mask(LOG_UNIMP, "gen_alc: undefined instruction 0x%x %s\n", opc, sm ? "(speculative)" : "");
|
||||||
|
|
|
@ -263,7 +263,8 @@ static void gen_cs1(DisasContext *dc)
|
||||||
unsigned int wbs = cs1 & 0x7f;
|
unsigned int wbs = cs1 & 0x7f;
|
||||||
|
|
||||||
if (ctop) {
|
if (ctop) {
|
||||||
tcg_gen_movi_i32(e2k_cs.wbs, wbs);
|
dc->is_call = true;
|
||||||
|
tcg_gen_movi_i32(e2k_cs.syscall_wbs, wbs * 2);
|
||||||
// my_printf ("call %%ctpr%d, wbs = 0x%x", ctop, wbs);
|
// my_printf ("call %%ctpr%d, wbs = 0x%x", ctop, wbs);
|
||||||
// print_ctcond (info, instr->ss & 0x1ff);
|
// print_ctcond (info, instr->ss & 0x1ff);
|
||||||
} else {
|
} else {
|
||||||
|
@ -324,116 +325,118 @@ static void gen_jmp(DisasContext *dc)
|
||||||
unsigned int cond_type = GET_FIELD(dc->bundle.ss, 5, 8);
|
unsigned int cond_type = GET_FIELD(dc->bundle.ss, 5, 8);
|
||||||
unsigned int ctpr = GET_FIELD(dc->bundle.ss, 10, 11);
|
unsigned int ctpr = GET_FIELD(dc->bundle.ss, 10, 11);
|
||||||
|
|
||||||
|
if (cond_type == 1) {
|
||||||
|
dc->base.is_jmp = STATIC_JUMP;
|
||||||
|
tcg_gen_movi_i64(dc->jmp.cond, 1);
|
||||||
|
} else {
|
||||||
|
dc->base.is_jmp = DYNAMIC_JUMP;
|
||||||
|
|
||||||
|
if (cond_type == 2 || cond_type == 6 || cond_type == 0xf) {
|
||||||
|
/* if pred is true */
|
||||||
|
tcg_gen_mov_i64(dc->jmp.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, dc->jmp.cond,
|
||||||
|
e2k_get_preg(dc, psrc), zero,
|
||||||
|
one, zero);
|
||||||
|
tcg_temp_free_i64(zero);
|
||||||
|
tcg_temp_free_i64(one);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: other kinds of conditions */
|
||||||
|
|
||||||
|
if (cond_type == 4
|
||||||
|
|| cond_type == 6
|
||||||
|
|| cond_type == 0xe)
|
||||||
|
{
|
||||||
|
if (cond_type == 6 || cond_type == 0xe) {
|
||||||
|
// or
|
||||||
|
}
|
||||||
|
|
||||||
|
// %LOOP_END
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cond_type == 5
|
||||||
|
|| cond_type == 7
|
||||||
|
|| cond_type == 0xf)
|
||||||
|
{
|
||||||
|
if(cond_type == 7
|
||||||
|
|| cond_type == 0xf)
|
||||||
|
{
|
||||||
|
// AND
|
||||||
|
}
|
||||||
|
// %NOT_LOOP_END
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cond_type == 8) {
|
||||||
|
// %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. */
|
||||||
|
if (psrc & 0xf) {
|
||||||
|
// static const int conv[] = {0, 1, 3, 4};
|
||||||
|
int i;
|
||||||
|
|
||||||
|
// %dt_al
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
if (psrc & (1 << i)) {
|
||||||
|
// i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* `lock_cond || pl_cond' control transfer conditions. */
|
||||||
|
if (cond_type == 9) {
|
||||||
|
unsigned int type = (psrc & 0x18) >> 3;
|
||||||
|
if (type == 0) {
|
||||||
|
// static const int cmp_num_to_alc[] = {0, 1, 3, 4};
|
||||||
|
// unsigned int cmp_num = (psrc & 0x6) >> 1;
|
||||||
|
// unsigned int neg = psrc & 0x1;
|
||||||
|
|
||||||
|
// my_printf ("%%MLOCK || %s%%cmp%d", neg ? "~" : "",
|
||||||
|
// cmp_num_to_alc[cmp_num]);
|
||||||
|
} else if (type == 1) {
|
||||||
|
// unsigned int cmp_jk = (psrc & 0x4) >> 2;
|
||||||
|
// unsigned int negj = (psrc & 0x2) >> 1;
|
||||||
|
// unsigned int negk = psrc & 0x1;
|
||||||
|
|
||||||
|
// my_printf ("%%MLOCK || %s%%cmp%d || %s%%cmp%d",
|
||||||
|
// negj ? "~" : "", cmp_jk == 0 ? 0 : 3,
|
||||||
|
// negk ? "~" : "", cmp_jk == 0 ? 1 : 4);
|
||||||
|
} else if (type == 2) {
|
||||||
|
// unsigned int clp_num = (psrc & 0x6) >> 1;
|
||||||
|
// unsigned int neg = psrc & 0x1;
|
||||||
|
|
||||||
|
// "%%MLOCK || %s%%clp%d", neg ? "~" : "", clp_num
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cond_type >= 0xa && cond_type <= 0xd) {
|
||||||
|
// reserved condition type
|
||||||
|
qemu_log_mask(LOG_UNIMP, "Undefined control transfer type %#x\n", cond_type);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* TODO: check CPU behavior if present ibranch and ctpr is not zero */
|
/* TODO: check CPU behavior if present ibranch and ctpr is not zero */
|
||||||
|
|
||||||
/* TODO: different kinds of ct */
|
/* TODO: different kinds of ct */
|
||||||
if (ctpr != 0) {
|
if (ctpr != 0) {
|
||||||
|
if (dc->is_call) {
|
||||||
|
/* TODO: call save state */
|
||||||
|
dc->call_ctpr = ctpr;
|
||||||
|
dc->base.is_jmp = DISAS_CALL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
TCGv_i64 t0 = tcg_temp_new_i64();
|
TCGv_i64 t0 = tcg_temp_new_i64();
|
||||||
|
|
||||||
/* TODO: use save_state */
|
|
||||||
tcg_gen_movi_i64(e2k_cs.pc, dc->pc);
|
|
||||||
gen_helper_check_syscall_ctpr(cpu_env, e2k_cs.ctprs[ctpr]);
|
|
||||||
tcg_gen_andi_i64(t0, e2k_cs.ctprs[ctpr], GEN_MASK(uint64_t, 0, 47));
|
tcg_gen_andi_i64(t0, e2k_cs.ctprs[ctpr], GEN_MASK(uint64_t, 0, 47));
|
||||||
tcg_gen_mov_tl(dc->jmp.dest, t0);
|
tcg_gen_mov_tl(dc->jmp.dest, t0);
|
||||||
|
|
||||||
tcg_temp_free_i64(t0);
|
tcg_temp_free_i64(t0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cond_type == 1) {
|
|
||||||
dc->base.is_jmp = STATIC_JUMP;
|
|
||||||
tcg_gen_movi_i64(dc->jmp.cond, 1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
dc->base.is_jmp = DYNAMIC_JUMP;
|
|
||||||
|
|
||||||
if (cond_type == 2 || cond_type == 6 || cond_type == 0xf) {
|
|
||||||
/* if pred is true */
|
|
||||||
tcg_gen_mov_i64(dc->jmp.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, dc->jmp.cond,
|
|
||||||
e2k_get_preg(dc, psrc), zero,
|
|
||||||
one, zero);
|
|
||||||
tcg_temp_free_i64(zero);
|
|
||||||
tcg_temp_free_i64(one);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO: other kinds of conditions */
|
|
||||||
|
|
||||||
if (cond_type == 4
|
|
||||||
|| cond_type == 6
|
|
||||||
|| cond_type == 0xe)
|
|
||||||
{
|
|
||||||
if (cond_type == 6 || cond_type == 0xe) {
|
|
||||||
// or
|
|
||||||
}
|
|
||||||
|
|
||||||
// %LOOP_END
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cond_type == 5
|
|
||||||
|| cond_type == 7
|
|
||||||
|| cond_type == 0xf)
|
|
||||||
{
|
|
||||||
if(cond_type == 7
|
|
||||||
|| cond_type == 0xf)
|
|
||||||
{
|
|
||||||
// AND
|
|
||||||
}
|
|
||||||
// %NOT_LOOP_END
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cond_type == 8) {
|
|
||||||
// %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. */
|
|
||||||
if (psrc & 0xf) {
|
|
||||||
// static const int conv[] = {0, 1, 3, 4};
|
|
||||||
int i;
|
|
||||||
|
|
||||||
// %dt_al
|
|
||||||
for (i = 0; i < 4; i++) {
|
|
||||||
if (psrc & (1 << i)) {
|
|
||||||
// i
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* `lock_cond || pl_cond' control transfer conditions. */
|
|
||||||
if (cond_type == 9) {
|
|
||||||
unsigned int type = (psrc & 0x18) >> 3;
|
|
||||||
if (type == 0) {
|
|
||||||
// static const int cmp_num_to_alc[] = {0, 1, 3, 4};
|
|
||||||
// unsigned int cmp_num = (psrc & 0x6) >> 1;
|
|
||||||
// unsigned int neg = psrc & 0x1;
|
|
||||||
|
|
||||||
// my_printf ("%%MLOCK || %s%%cmp%d", neg ? "~" : "",
|
|
||||||
// cmp_num_to_alc[cmp_num]);
|
|
||||||
} else if (type == 1) {
|
|
||||||
// unsigned int cmp_jk = (psrc & 0x4) >> 2;
|
|
||||||
// unsigned int negj = (psrc & 0x2) >> 1;
|
|
||||||
// unsigned int negk = psrc & 0x1;
|
|
||||||
|
|
||||||
// my_printf ("%%MLOCK || %s%%cmp%d || %s%%cmp%d",
|
|
||||||
// negj ? "~" : "", cmp_jk == 0 ? 0 : 3,
|
|
||||||
// negk ? "~" : "", cmp_jk == 0 ? 1 : 4);
|
|
||||||
} else if (type == 2) {
|
|
||||||
// unsigned int clp_num = (psrc & 0x6) >> 1;
|
|
||||||
// unsigned int neg = psrc & 0x1;
|
|
||||||
|
|
||||||
// "%%MLOCK || %s%%clp%d", neg ? "~" : "", clp_num
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cond_type >= 0xa && cond_type <= 0xd) {
|
|
||||||
// reserved condition type
|
|
||||||
qemu_log_mask(LOG_UNIMP, "Undefined control transfer type %#x\n", cond_type);
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2k_control_gen(DisasContext *dc)
|
void e2k_control_gen(DisasContext *dc)
|
||||||
|
|
Loading…
Reference in New Issue