target: e2k: Add mova stubs.
This commit is contained in:
parent
250a648edf
commit
7ff1f54b8f
@ -3,15 +3,16 @@ e2k_ss.add(files(
|
||||
'cpu.c',
|
||||
'gdbstub.c',
|
||||
'helper.c',
|
||||
'helper_aau.c',
|
||||
'helper_int.c',
|
||||
'helper_sm.c',
|
||||
'helper_vec.c',
|
||||
'helper_aau.c',
|
||||
'translate.c',
|
||||
'translate/state.c',
|
||||
'translate/control.c',
|
||||
'translate/alc.c',
|
||||
'translate/aau.c',
|
||||
'translate/control.c',
|
||||
'translate/plu.c',
|
||||
'translate/state.c',
|
||||
))
|
||||
|
||||
# no softmmu support yet
|
||||
|
@ -282,6 +282,8 @@ static inline void do_execute(DisasContext *ctx)
|
||||
e2k_alc_execute(ctx, i);
|
||||
}
|
||||
}
|
||||
|
||||
e2k_aau_execute(ctx);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -295,6 +297,7 @@ static inline void do_execute(DisasContext *ctx)
|
||||
static inline void do_commit(DisasContext *ctx)
|
||||
{
|
||||
e2k_alc_commit(ctx);
|
||||
e2k_aau_commit(ctx);
|
||||
e2k_plu_commit(ctx);
|
||||
e2k_commit_stubs(ctx);
|
||||
}
|
||||
|
@ -132,6 +132,21 @@ typedef struct {
|
||||
};
|
||||
} AlResult;
|
||||
|
||||
typedef enum {
|
||||
AAU_RESULT_NONE,
|
||||
AAU_RESULT_REG32,
|
||||
AAU_RESULT_REG64,
|
||||
} AauResultType;
|
||||
|
||||
typedef struct {
|
||||
AauResultType type;
|
||||
TCGv_i32 index;
|
||||
union {
|
||||
TCGv_i32 v32;
|
||||
TCGv_i64 v64;
|
||||
};
|
||||
} AauResult;
|
||||
|
||||
typedef struct {
|
||||
bool is_set;
|
||||
TCGv_i64 value;
|
||||
@ -183,10 +198,25 @@ typedef struct DisasContext {
|
||||
TCGv_i64 cond[6];
|
||||
AlResult al_results[6];
|
||||
AlCond al_cond[6];
|
||||
AauResult aau_results[4];
|
||||
PlResult pl_results[3];
|
||||
ControlTransfer ct;
|
||||
} DisasContext;
|
||||
|
||||
/* exception generated in translation time */
|
||||
void e2k_tr_gen_exception(DisasContext *dc, int which);
|
||||
|
||||
/* exception generated in runtime */
|
||||
static inline void e2k_gen_exception(int excp)
|
||||
{
|
||||
TCGv_i32 t0 = tcg_const_i32(excp);
|
||||
|
||||
// TODO: check if need to save state
|
||||
gen_helper_raise_exception(cpu_env, t0);
|
||||
|
||||
tcg_temp_free_i32(t0);
|
||||
}
|
||||
|
||||
static inline void e2k_gen_mask_i64(TCGv_i64 ret, TCGv_i64 len)
|
||||
{
|
||||
TCGv_i64 one = tcg_const_i64(1);
|
||||
@ -306,44 +336,6 @@ static inline void e2k_gen_lcntex(TCGv_i32 ret)
|
||||
tcg_temp_free_i32(t0);
|
||||
}
|
||||
|
||||
static inline bool is_load_chan(int chan)
|
||||
{
|
||||
switch(chan) {
|
||||
case 0:
|
||||
case 2:
|
||||
case 3:
|
||||
case 5:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool is_store_chan(int chan)
|
||||
{
|
||||
switch(chan) {
|
||||
case 2:
|
||||
case 5:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool is_cmp_chan(int chan)
|
||||
{
|
||||
switch(chan) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 3:
|
||||
case 4:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool is_div_chan(int chan) {
|
||||
return chan == 5;
|
||||
}
|
||||
|
||||
void e2k_gen_store_preg(int idx, TCGv_i64 val);
|
||||
|
||||
void e2k_gen_reg_tag_read_i64(TCGv_i32 ret, TCGv_i32 idx);
|
||||
@ -381,6 +373,18 @@ void e2k_gen_reg_tag_check_i32(TCGv_i32 ret, TCGv_i32 tag);
|
||||
void e2k_gen_reg_index_from_wregi(TCGv_i32 ret, int idx);
|
||||
void e2k_gen_reg_index_from_bregi(TCGv_i32 ret, int idx);
|
||||
void e2k_gen_reg_index_from_gregi(TCGv_i32 ret, int idx);
|
||||
static inline void e2k_gen_reg_index(TCGv_i32 ret, uint8_t arg)
|
||||
{
|
||||
if (IS_BASED(arg)) {
|
||||
e2k_gen_reg_index_from_bregi(ret, GET_BASED(arg));
|
||||
} else if (IS_REGULAR(arg)) {
|
||||
e2k_gen_reg_index_from_wregi(ret, GET_REGULAR(arg));
|
||||
} else if (IS_GLOBAL(arg)) {
|
||||
e2k_gen_reg_index_from_gregi(ret, GET_GLOBAL(arg));
|
||||
} else {
|
||||
e2k_gen_exception(E2K_EXCP_ILLOPN);
|
||||
}
|
||||
}
|
||||
|
||||
void e2k_gen_reg_read_i64(TCGv_i64 ret, TCGv_i32 idx);
|
||||
void e2k_gen_reg_read_i32(TCGv_i32 ret, TCGv_i32 idx);
|
||||
@ -402,25 +406,14 @@ static inline void e2k_gen_cond_i64(DisasContext *ctx, TCGv_i64 ret,
|
||||
tcg_temp_free_i32(t0);
|
||||
}
|
||||
|
||||
/* exception generated in translation time */
|
||||
void e2k_tr_gen_exception(DisasContext *dc, int which);
|
||||
|
||||
/* exception generated in runtime */
|
||||
static inline void e2k_gen_exception(int excp)
|
||||
{
|
||||
TCGv_i32 t0 = tcg_const_i32(excp);
|
||||
|
||||
// TODO: check if need to save state
|
||||
gen_helper_raise_exception(cpu_env, t0);
|
||||
|
||||
tcg_temp_free_i32(t0);
|
||||
}
|
||||
|
||||
void e2k_control_gen(DisasContext *dc);
|
||||
|
||||
void e2k_alc_execute(DisasContext *ctx, int index);
|
||||
void e2k_alc_commit(DisasContext *dc);
|
||||
|
||||
void e2k_aau_execute(DisasContext *ctx);
|
||||
void e2k_aau_commit(DisasContext *ctx);
|
||||
|
||||
void e2k_plu_execute(DisasContext *ctx);
|
||||
void e2k_plu_commit(DisasContext *ctx);
|
||||
|
||||
|
118
target/e2k/translate/aau.c
Normal file
118
target/e2k/translate/aau.c
Normal file
@ -0,0 +1,118 @@
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu.h"
|
||||
#include "exec/log.h"
|
||||
#include "translate.h"
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
struct {
|
||||
uint16_t am: 1;
|
||||
uint16_t ind: 5;
|
||||
uint16_t area: 6;
|
||||
uint16_t opc: 3;
|
||||
uint16_t be: 1;
|
||||
};
|
||||
uint16_t aas;
|
||||
};
|
||||
uint8_t dst;
|
||||
} Instr;
|
||||
|
||||
void e2k_aau_execute(DisasContext *ctx)
|
||||
{
|
||||
const UnpackedBundle *bundle = &ctx->bundle;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
Instr instr = { 0 };
|
||||
AauResult *res = &ctx->aau_results[i];
|
||||
|
||||
instr.aas = bundle->aas[i + 2];
|
||||
instr.dst = extract16(bundle->aas[i / 2], ((i & 1) ^ 1) * 8, 8);
|
||||
if (!bundle->aas_present[i + 2] || instr.opc == 0) {
|
||||
res->type = AAU_RESULT_NONE;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (instr.be) {
|
||||
// TODO: aas.be
|
||||
qemu_log_mask(LOG_UNIMP, "0x%lx: aas.be is not implemented\n",
|
||||
ctx->pc);
|
||||
abort();
|
||||
}
|
||||
|
||||
if (instr.am) {
|
||||
// TODO: aas.am
|
||||
qemu_log_mask(LOG_UNIMP, "0x%lx: aas.be is not implemented\n",
|
||||
ctx->pc);
|
||||
abort();
|
||||
}
|
||||
|
||||
switch(instr.opc) {
|
||||
case 1:
|
||||
// TODO: movab
|
||||
qemu_log_mask(LOG_UNIMP, "0x%lx: movab is not implemented\n",
|
||||
ctx->pc);
|
||||
abort();
|
||||
break;
|
||||
case 2:
|
||||
// TODO: movah
|
||||
qemu_log_mask(LOG_UNIMP, "0x%lx: movah is not implemented\n",
|
||||
ctx->pc);
|
||||
abort();
|
||||
break;
|
||||
case 3:
|
||||
// TODO: movaw
|
||||
qemu_log_mask(LOG_UNIMP, "0x%lx: movaw is not implemented\n",
|
||||
ctx->pc);
|
||||
abort();
|
||||
break;
|
||||
case 4:
|
||||
// TODO: movad
|
||||
qemu_log_mask(LOG_UNIMP, "0x%lx: movad is not implemented\n",
|
||||
ctx->pc);
|
||||
abort();
|
||||
break;
|
||||
case 5:
|
||||
// TODO: movaq
|
||||
qemu_log_mask(LOG_UNIMP, "0x%lx: movaq is not implemented\n",
|
||||
ctx->pc);
|
||||
abort();
|
||||
break;
|
||||
case 7:
|
||||
// TODO: movaqp
|
||||
qemu_log_mask(LOG_UNIMP, "0x%lx: movaqp is not implemented\n",
|
||||
ctx->pc);
|
||||
abort();
|
||||
break;
|
||||
default:
|
||||
e2k_tr_gen_exception(ctx, E2K_EXCP_ILLOPC);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void e2k_aau_commit(DisasContext *ctx)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
AauResult *res = &ctx->aau_results[i];
|
||||
TCGv_i32 zero = tcg_const_i32(0);
|
||||
|
||||
// TODO: aau.tags
|
||||
switch(res->type) {
|
||||
case AAU_RESULT_REG32:
|
||||
e2k_gen_reg_tag_write_i32(zero, res->index);
|
||||
e2k_gen_reg_write_i32(res->v32, res->index);
|
||||
break;
|
||||
case AAU_RESULT_REG64:
|
||||
e2k_gen_reg_tag_write_i64(zero, res->index);
|
||||
e2k_gen_reg_write_i64(res->v64, res->index);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
tcg_temp_free_i32(zero);
|
||||
}
|
||||
}
|
@ -81,24 +81,11 @@ static inline bool is_chan_0235(int c)
|
||||
return is_chan_03(c) || is_chan_25(c);
|
||||
}
|
||||
|
||||
static inline void gen_reg_index(TCGv_i32 ret, uint8_t arg)
|
||||
{
|
||||
if (IS_BASED(arg)) {
|
||||
e2k_gen_reg_index_from_bregi(ret, GET_BASED(arg));
|
||||
} else if (IS_REGULAR(arg)) {
|
||||
e2k_gen_reg_index_from_wregi(ret, GET_REGULAR(arg));
|
||||
} else if (IS_GLOBAL(arg)) {
|
||||
e2k_gen_reg_index_from_gregi(ret, GET_GLOBAL(arg));
|
||||
} else {
|
||||
e2k_gen_exception(E2K_EXCP_ILLOPN);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void gen_reg_i64(DisasContext *ctx, Src64 *ret, uint8_t arg)
|
||||
{
|
||||
TCGv_i32 t0 = tcg_temp_new_i32();
|
||||
|
||||
gen_reg_index(t0, arg);
|
||||
e2k_gen_reg_index(t0, arg);
|
||||
ret->tag = e2k_get_temp_i32(ctx);
|
||||
ret->value = e2k_get_temp_i64(ctx);
|
||||
e2k_gen_reg_tag_read_i64(ret->tag, t0);
|
||||
@ -111,7 +98,7 @@ static inline void gen_reg_i32(DisasContext *ctx, Src32 *ret, uint8_t arg)
|
||||
{
|
||||
TCGv_i32 t0 = tcg_temp_new_i32();
|
||||
|
||||
gen_reg_index(t0, arg);
|
||||
e2k_gen_reg_index(t0, arg);
|
||||
ret->tag = e2k_get_temp_i32(ctx);
|
||||
ret->value = e2k_get_temp_i32(ctx);
|
||||
e2k_gen_reg_tag_read_i32(ret->tag, t0);
|
||||
@ -373,7 +360,7 @@ static inline void set_al_result_reg64_tag(DisasContext *ctx, int chan,
|
||||
res->reg.v64 = value;
|
||||
res->reg.tag = tag;
|
||||
res->reg.index = e2k_get_temp_i32(ctx);
|
||||
gen_reg_index(res->reg.index, arg);
|
||||
e2k_gen_reg_index(res->reg.index, arg);
|
||||
}
|
||||
}
|
||||
|
||||
@ -405,7 +392,7 @@ static inline void set_al_result_reg32_tag(DisasContext *ctx, int chan,
|
||||
res->reg.v32 = value;
|
||||
res->reg.tag = tag;
|
||||
res->reg.index = e2k_get_temp_i32(ctx);
|
||||
gen_reg_index(res->reg.index, arg);
|
||||
e2k_gen_reg_index(res->reg.index, arg);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1166,10 +1153,12 @@ static MemOp gen_mas(DisasContext *ctx, int chan, MemOp memop, TCGv_i64 addr)
|
||||
uint8_t mas = ctx->mas[chan];
|
||||
|
||||
if ((mas & 0x7) == 7) {
|
||||
int opc = mas >> 3;
|
||||
// TODO: special mas
|
||||
// e2k_tr_gen_exception(ctx, E2K_EXCP_ILLOPC);
|
||||
qemu_log_mask(LOG_UNIMP, "0x%lx: mas=0x%x is not implemented!\n",
|
||||
ctx->pc, mas);
|
||||
qemu_log_mask(LOG_UNIMP, "0x%lx: mas=%#x, opc=%#x is not implemented!\n",
|
||||
ctx->pc, mas, opc);
|
||||
return 0;
|
||||
} else if (mas) {
|
||||
int mod = extract8(mas, 0, 3);
|
||||
// int dc = extract8(mas, 5, 2);
|
||||
@ -1177,8 +1166,8 @@ static MemOp gen_mas(DisasContext *ctx, int chan, MemOp memop, TCGv_i64 addr)
|
||||
if (mod != 0) {
|
||||
// TODO: mas modes
|
||||
// e2k_tr_gen_exception(ctx, E2K_EXCP_ILLOPC);
|
||||
qemu_log_mask(LOG_UNIMP, "0x%lx: mas=0x%x is not implemented!\n",
|
||||
ctx->pc, mas);
|
||||
qemu_log_mask(LOG_UNIMP, "0x%lx: mas=%#x, mod=%#x is not implemented!\n",
|
||||
ctx->pc, mas, mod);
|
||||
}
|
||||
|
||||
memop |= GET_BIT(mas, 3) ? MO_BE : MO_LE;
|
||||
@ -1224,6 +1213,39 @@ static void gen_ld(DisasContext *ctx, int chan, MemOp memop)
|
||||
tcg_temp_free_i64(t0);
|
||||
}
|
||||
|
||||
static void gen_st(DisasContext *ctx, int chan, MemOp memop)
|
||||
{
|
||||
bool sm = GET_BIT(ctx->bundle.als[chan], 31);
|
||||
TCGLabel *l0 = gen_new_label();
|
||||
Src64 s1 = get_src1_i64(ctx, chan);
|
||||
Src64 s2 = get_src2_i64(ctx, chan);
|
||||
Src64 s4 = get_src4_i64(ctx, chan);
|
||||
TCGv_i64 t0 = tcg_temp_local_new_i64();
|
||||
|
||||
gen_tag_check(ctx, sm, s1.tag);
|
||||
gen_tag_check(ctx, sm, s2.tag);
|
||||
gen_tag_check(ctx, sm, s4.tag);
|
||||
tcg_gen_add_i64(t0, s1.value, s2.value);
|
||||
memop = gen_mas(ctx, chan, memop, t0);
|
||||
|
||||
if (memop == 0) {
|
||||
// TODO: memop is zero after gen_mas
|
||||
tcg_gen_br(l0);
|
||||
}
|
||||
|
||||
if (sm) {
|
||||
TCGv_i32 t1 = tcg_temp_new_i32();
|
||||
gen_helper_probe_write_access(t1, cpu_env, t0);
|
||||
tcg_gen_brcondi_i32(TCG_COND_EQ, t1, 0, l0);
|
||||
tcg_temp_free_i32(t1);
|
||||
}
|
||||
|
||||
tcg_gen_qemu_st_i64(s4.value, t0, ctx->mmuidx, memop);
|
||||
gen_set_label(l0);
|
||||
|
||||
tcg_temp_free_i64(t0);
|
||||
}
|
||||
|
||||
static void gen_staa_i64(DisasContext *ctx, int chan)
|
||||
{
|
||||
uint32_t als = ctx->bundle.als[chan];
|
||||
@ -1327,34 +1349,6 @@ static void gen_staa_i32(DisasContext *ctx, int chan)
|
||||
tcg_temp_free_i32(t0);
|
||||
}
|
||||
|
||||
static void gen_st(DisasContext *ctx, int chan, MemOp memop)
|
||||
{
|
||||
bool sm = GET_BIT(ctx->bundle.als[chan], 31);
|
||||
TCGLabel *l0 = gen_new_label();
|
||||
Src64 s1 = get_src1_i64(ctx, chan);
|
||||
Src64 s2 = get_src2_i64(ctx, chan);
|
||||
Src64 s4 = get_src4_i64(ctx, chan);
|
||||
TCGv_i64 t0 = tcg_temp_local_new_i64();
|
||||
|
||||
gen_tag_check(ctx, sm, s1.tag);
|
||||
gen_tag_check(ctx, sm, s2.tag);
|
||||
gen_tag_check(ctx, sm, s4.tag);
|
||||
tcg_gen_add_i64(t0, s1.value, s2.value);
|
||||
memop = gen_mas(ctx, chan, memop, t0);
|
||||
|
||||
if (sm) {
|
||||
TCGv_i32 t1 = tcg_temp_new_i32();
|
||||
gen_helper_probe_write_access(t1, cpu_env, t0);
|
||||
tcg_gen_brcondi_i32(TCG_COND_EQ, t1, 0, l0);
|
||||
tcg_temp_free_i32(t1);
|
||||
}
|
||||
|
||||
tcg_gen_qemu_st_i64(s4.value, t0, ctx->mmuidx, memop);
|
||||
gen_set_label(l0);
|
||||
|
||||
tcg_temp_free_i64(t0);
|
||||
}
|
||||
|
||||
static void gen_alopf1_i64(DisasContext *ctx, int chan,
|
||||
void (*op)(TCGv_i64, TCGv_i64, TCGv_i64))
|
||||
{
|
||||
@ -2236,14 +2230,14 @@ static void execute_ext_0b(DisasContext *ctx, Instr *instr)
|
||||
{
|
||||
switch(instr->opc1) {
|
||||
case 0x6c:
|
||||
if (is_cmp_chan(instr->chan) && ctx->version >= 4) {
|
||||
if (is_chan_0134(instr->chan) && ctx->version >= 4) {
|
||||
/* insfs */
|
||||
gen_alopf21_i32(ctx, instr, gen_insert_field_i32);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 0x6d:
|
||||
if (is_cmp_chan(instr->chan) && ctx->version>= 4) {
|
||||
if (is_chan_0134(instr->chan) && ctx->version>= 4) {
|
||||
/* insfd */
|
||||
gen_alopf21_i64(ctx, instr, gen_insert_field_i64);
|
||||
return;
|
||||
@ -2259,7 +2253,7 @@ static void execute_ext_0f(DisasContext *ctx, Instr *instr)
|
||||
{
|
||||
switch(instr->opc1) {
|
||||
case 0x4d:
|
||||
if (is_cmp_chan(instr->chan) && ctx->version >= 2) {
|
||||
if (is_chan_0134(instr->chan) && ctx->version >= 2) {
|
||||
/* pshufb */
|
||||
gen_alopf21_i64(ctx, instr, gen_helper_packed_shuffle_i64);
|
||||
return;
|
||||
|
Loading…
Reference in New Issue
Block a user