target: e2k: Hack delay %rN index gen for result.

This commit is contained in:
Denis Drakhnia 2020-12-06 15:59:06 +02:00 committed by Denis Drakhnia
parent 1ad7988e9a
commit 8e033a839e
4 changed files with 105 additions and 58 deletions

View File

@ -286,6 +286,7 @@ static inline void do_execute(DisasContext *ctx)
* */
static inline void do_commit(DisasContext *ctx)
{
e2k_control_window_change(ctx);
e2k_alc_commit(ctx);
e2k_aau_commit(ctx);
e2k_plu_commit(ctx);

View File

@ -114,6 +114,7 @@ typedef struct {
AlResultType type;
union {
struct {
uint8_t dst; /* %rN, 1st phase */
TCGv_i32 index;
union {
TCGv_i32 v32;
@ -407,6 +408,7 @@ static inline void e2k_gen_cond_i64(DisasContext *ctx, TCGv_i64 ret,
}
void e2k_control_execute(DisasContext *ctx);
void e2k_control_window_change(DisasContext *ctx);
void e2k_stubs_commit(DisasContext *ctx);
void e2k_alc_execute(DisasContext *ctx);

View File

@ -360,7 +360,12 @@ 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);
e2k_gen_reg_index(res->reg.index, arg);
if (IS_REGULAR(arg)) {
res->reg.dst = arg;
} else {
res->reg.dst = 0;
e2k_gen_reg_index(res->reg.index, arg);
}
}
}
@ -392,7 +397,12 @@ 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);
e2k_gen_reg_index(res->reg.index, arg);
if (IS_REGULAR(arg)) {
res->reg.dst = arg;
} else {
res->reg.dst = 0;
e2k_gen_reg_index(res->reg.index, arg);
}
}
}
@ -2371,6 +2381,17 @@ void e2k_alc_commit(DisasContext *ctx)
{
unsigned int i;
for (i = 0; i < 6; i++) {
AlResult *res = &ctx->al_results[i];
if (res->type == AL_RESULT_REG32 || res->type == AL_RESULT_REG64) {
uint8_t dst = res->reg.dst;
if (IS_REGULAR(dst)) {
e2k_gen_reg_index_from_wregi(res->reg.index, GET_REGULAR(dst));
}
}
}
for (i = 0; i < 6; i++) {
TCGLabel *l0 = gen_new_label();
AlResult *res = &ctx->al_results[i];

View File

@ -363,51 +363,7 @@ static void gen_cs1(DisasContext *dc)
unsigned int cs1 = bundle->cs1;
unsigned int opc = (cs1 & 0xf0000000) >> 28;
if (opc == SETR0 || opc == SETR1 || opc == SETBR) {
unsigned int setbp = (cs1 & 0x08000000) >> 27;
unsigned int setbn = (cs1 & 0x04000000) >> 26;
if (opc == SETR1) {
if (! bundle->lts_present[0]) {
e2k_tr_gen_exception(dc, E2K_EXCP_ILLOPC);
} else {
/* Find out if VFRPSZ is always encoded together with SETWD. This
seems to be the case even if no SETWD has been explicitly
specified. */
// unsigned int rpsz = (bundle->lts[0] & 0x0001f000) >> 12;
abort();
}
}
if (opc == SETR0 || opc == SETR1) {
if (! bundle->lts_present[0]) {
e2k_tr_gen_exception(dc, E2K_EXCP_ILLOPC);
} else {
TCGv_i32 lts = tcg_const_i32(bundle->lts[0]);
gen_helper_setwd(cpu_env, lts);
tcg_temp_free_i32(lts);
}
}
if (setbn) {
int rbs = GET_FIELD(cs1, BR_RBS_OFF, BR_RBS_LEN);
int rsz = GET_FIELD(cs1, BR_RSZ_OFF, BR_RSZ_LEN);
int rcur = GET_FIELD(cs1, BR_RCUR_OFF, BR_RCUR_LEN);
tcg_gen_movi_i32(e2k_cs.boff, rbs * 2);
tcg_gen_movi_i32(e2k_cs.bsize, (rsz + 1) * 2);
tcg_gen_movi_i32(e2k_cs.bcur, rcur * 2);
}
if (setbp) {
int psz = GET_FIELD(cs1, BR_PSZ_OFF, BR_PSZ_LEN);
tcg_gen_movi_i32(e2k_cs.psize, psz);
tcg_gen_movi_i32(e2k_cs.pcur, 0);
}
} else if (opc == SETEI) {
if (opc == SETEI) {
bool sft = GET_BIT(cs1, 27);
if (sft) {
@ -498,8 +454,6 @@ static void gen_cs1(DisasContext *dc)
// TODO: vfbg
abort();
} else {
e2k_tr_gen_exception(dc, E2K_EXCP_ILLOPC);
}
}
@ -620,19 +574,88 @@ static void gen_jmp(DisasContext *dc)
}
}
void e2k_control_execute(DisasContext *dc)
void e2k_control_window_change(DisasContext *dc)
{
dc->ct.type = CT_NONE;
enum {
SETR0,
SETR1,
SETEI,
WAIT,
SETBR,
CALL,
MAS_OPC,
FLUSHR,
BG
};
if (dc->bundle.ss_present) {
gen_jmp(dc);
const UnpackedBundle *bundle = &dc->bundle;
uint32_t cs1 = bundle->cs1;
int opc = extract32(cs1, 28, 4);
if (!dc->bundle.cs1_present) {
return;
}
if (dc->bundle.cs0_present) {
gen_cs0(dc);
}
if (opc == SETR0 || opc == SETR1 || opc == SETBR) {
bool setbp = (cs1 >> 27) & 1;
bool setbn = (cs1 >> 26) & 1;
if (dc->bundle.cs1_present) {
gen_cs1(dc);
if (opc == SETR1) {
if (!bundle->lts_present[0]) {
e2k_tr_gen_exception(dc, E2K_EXCP_ILLOPC);
} else {
/* Find out if VFRPSZ is always encoded together with SETWD. This
seems to be the case even if no SETWD has been explicitly
specified. */
// unsigned int rpsz = (bundle->lts[0] & 0x0001f000) >> 12;
qemu_log_mask(LOG_UNIMP, "0x%lx: vfrpsz is not implemented!",
dc->pc);
}
}
if (opc == SETR0 || opc == SETR1) {
if (!bundle->lts_present[0]) {
e2k_tr_gen_exception(dc, E2K_EXCP_ILLOPC);
} else {
TCGv_i32 lts = tcg_const_i32(bundle->lts[0]);
gen_helper_setwd(cpu_env, lts);
tcg_temp_free_i32(lts);
}
}
if (setbn) {
int rbs = GET_FIELD(cs1, BR_RBS_OFF, BR_RBS_LEN);
int rsz = GET_FIELD(cs1, BR_RSZ_OFF, BR_RSZ_LEN);
int rcur = GET_FIELD(cs1, BR_RCUR_OFF, BR_RCUR_LEN);
tcg_gen_movi_i32(e2k_cs.boff, rbs * 2);
tcg_gen_movi_i32(e2k_cs.bsize, (rsz + 1) * 2);
tcg_gen_movi_i32(e2k_cs.bcur, rcur * 2);
}
if (setbp) {
int psz = GET_FIELD(cs1, BR_PSZ_OFF, BR_PSZ_LEN);
tcg_gen_movi_i32(e2k_cs.psize, psz);
tcg_gen_movi_i32(e2k_cs.pcur, 0);
}
}
}
void e2k_control_execute(DisasContext *ctx)
{
ctx->ct.type = CT_NONE;
if (ctx->bundle.ss_present) {
gen_jmp(ctx);
}
if (ctx->bundle.cs0_present) {
gen_cs0(ctx);
}
if (ctx->bundle.cs1_present) {
gen_cs1(ctx);
}
}