e2k: Decode/execute ct cond after alc execution.

This commit is contained in:
Denis Drakhnia 2021-01-07 23:17:12 +02:00 committed by Denis Drakhnia
parent dae0735e36
commit 5f665e70ae
3 changed files with 12 additions and 19 deletions

View File

@ -273,6 +273,9 @@ static inline void do_execute(DisasContext *ctx)
{
e2k_control_execute(ctx);
e2k_alc_execute(ctx);
if (ctx->bundle.ss_present) {
e2k_decode_jmp(ctx);
}
e2k_aau_execute(ctx);
e2k_plu_execute(ctx);
}

View File

@ -559,6 +559,7 @@ static inline void e2k_gen_is_loop_end_i32(TCGv_i32 ret)
tcg_temp_free_i32(t0);
}
void e2k_decode_jmp(DisasContext *ctx);
void e2k_control_execute(DisasContext *ctx);
void e2k_control_window_change(DisasContext *ctx);
void e2k_stubs_commit(DisasContext *ctx);

View File

@ -222,14 +222,8 @@ static void gen_cs0(DisasContext *dc)
/* CS1.param.ctopc == HCALL */
&& (bundle->cs1 & 0x380) >> 7 == 2))
{
if (type == IBRANCH && dc->ct.type == CT_NONE) {
/* C0F2 has `disp' field. In `C0F1' it's called `param'. Is this
the only difference between these two formats? Funnily enough,
DONE is also C0F2 and thus has `disp', though it obviously
makes no sense for it. */
uint32_t disp = (cs0 & 0x0fffffff);
/* Calculate a signed displacement in bytes. */
int32_t sdisp = ((int32_t) (disp << 4)) >> 1;
if (type == IBRANCH) {
int32_t sdisp = sextract32(cs0, 0, 28) << 3;
dc->ct.type = CT_IBRANCH;
dc->ct.u.target = dc->pc + sdisp;
} else {
@ -244,9 +238,7 @@ static void gen_cs0(DisasContext *dc)
}
int ipd = bundle->ss_present ? GET_FIELD(bundle->ss, 30, 2) : 3;
if (type == DISP || type == LDISP) {
unsigned int disp = GET_FIELD(cs0, 0, 28);
/* Calculate a signed displacement in bytes. */
int sdisp = ((int) (disp << 4)) >> 1;
int32_t sdisp = sextract32(cs0, 0, 28) << 3;
uint64_t reg = (dc->pc + sdisp) |
((uint64_t) CTPR_TAG_DISP << CTPR_TAG_OFF) |
((uint64_t) ipd << CTPR_IPD_OFF);
@ -386,8 +378,7 @@ static void gen_cs1(DisasContext *dc)
} else {
unsigned int cs1_ctopc = (cs1 & 0x380) >> 7;
/* CS1.param.ctpopc == HCALL. CS0 is required to encode HCALL. */
if (cs1_ctopc == 2 && bundle->cs0_present &&
dc->ct.type == CT_NONE)
if (cs1_ctopc == 2 && bundle->cs0_present)
{
unsigned int cs0 = bundle->cs0;
unsigned int cs0_opc = (cs0 & 0xf0000000) >> 28;
@ -425,13 +416,15 @@ static void gen_cs1(DisasContext *dc)
}
}
static void gen_jmp(DisasContext *ctx)
void e2k_decode_jmp(DisasContext *ctx)
{
int cond_type = extract32(ctx->bundle.ss, 5, 4);
int ctpr = extract32(ctx->bundle.ss, 10, 2);
if (ctpr != 0) {
ctx->ct.type = CT_JUMP;
if (ctx->ct.type == CT_NONE) {
ctx->ct.type = CT_JUMP;
}
ctx->ct.u.ctpr = e2k_cs.ctprs[ctpr - 1];
}
@ -669,10 +662,6 @@ void e2k_control_execute(DisasContext *ctx)
gen_prologue_epilogue(ctx);
if (ctx->bundle.ss_present) {
gen_jmp(ctx);
}
if (ctx->bundle.cs0_present) {
gen_cs0(ctx);
}