target: e2k: Remove merge condition from Instr.

This commit is contained in:
Denis Drakhnia 2020-12-08 10:00:46 +02:00 committed by Denis Drakhnia
parent 93acd43783
commit 7578f94f7c

View File

@ -58,7 +58,6 @@ typedef struct {
uint16_t unused5: 8; uint16_t unused5: 8;
}; };
}; };
TCGv_i32 mrgc;
} Instr; } Instr;
static inline bool is_chan_03(int c) static inline bool is_chan_03(int c)
@ -548,42 +547,27 @@ static inline void gen_am_cond_i32(DisasContext *ctx, TCGv_i32 ret, int chan,
tcg_temp_free_i32(t0); tcg_temp_free_i32(t0);
} }
static inline void gen_mrgc_i64(DisasContext *ctx, int chan, TCGv_i64 ret) static inline void gen_mrgc_i32(DisasContext *ctx, int chan, TCGv_i32 ret)
{ {
uint16_t rlp = find_mrgc(ctx, chan); uint16_t rlp = find_mrgc(ctx, chan);
TCGv_i64 t0 = tcg_temp_new_i64();
e2k_gen_cond_i64(ctx, t0, rlp & 0x7f);
tcg_gen_xori_i64(ret, t0, GET_BIT(rlp, 7 + chan % 3));
tcg_temp_free_i64(t0);
}
static inline void gen_mrgc_i32(DisasContext *dc, int chan, TCGv_i32 ret)
{
TCGv_i64 t0 = tcg_temp_new_i64();
gen_mrgc_i64(dc, chan, t0);
tcg_gen_extrl_i64_i32(ret, t0);
tcg_temp_free(t0);
}
static inline Instr instr_new(DisasContext *ctx, int chan)
{
uint16_t rlp = find_mrgc(ctx, chan);
Instr ret = { 0 };
ret.chan = chan;
ret.als = ctx->bundle.als[chan];
ret.ales = ctx->bundle.ales[chan];
if (rlp) { if (rlp) {
TCGv_i32 t0 = tcg_temp_new_i32(); int psrc = extract16(rlp, 0, 7);
e2k_gen_cond_i32(ctx, t0, rlp & 0x7f);
ret.mrgc = e2k_get_temp_i32(ctx);
tcg_gen_xori_i32(ret.mrgc, t0, GET_BIT(rlp, 7 + chan % 3));
tcg_temp_free_i32(t0);
}
return ret; if (GET_BIT(rlp, 7 + chan % 3)) {
TCGv_i32 t0 = tcg_temp_new_i32();
e2k_gen_cond_i32(ctx, t0, psrc);
tcg_gen_setcondi_i32(TCG_COND_EQ, ret, t0, 0);
tcg_temp_free_i32(t0);
} else {
e2k_gen_cond_i32(ctx, ret, psrc);
}
} else {
/* Undefined behavior if MRGC is not provided but CPU returns src2. */
tcg_gen_movi_i32(ret, 0);
}
} }
static inline void gen_andn_i32(TCGv_i32 ret, TCGv_i32 src1, TCGv_i32 src2) static inline void gen_andn_i32(TCGv_i32 ret, TCGv_i32 src1, TCGv_i32 src2)
@ -924,19 +908,23 @@ static inline void gen_movehl_i64(TCGv_i64 ret, TCGv_i64 x, TCGv_i64 y)
tcg_temp_free_i32(lo); tcg_temp_free_i32(lo);
} }
static inline void gen_merge_i32(TCGv_i32 ret, TCGv_i32 x, TCGv_i32 y, TCGv_i32 cond) static inline void gen_merge_i32(TCGv_i32 ret, TCGv_i32 src1, TCGv_i32 src2,
TCGv_i32 cond)
{ {
TCGv_i32 zero = tcg_const_i32(0); TCGv_i32 zero = tcg_const_i32(0);
tcg_gen_movcond_i32(TCG_COND_EQ, ret, cond, zero, x, y); tcg_gen_movcond_i32(TCG_COND_EQ, ret, cond, zero, src1, src2);
tcg_temp_free_i32(zero); tcg_temp_free_i32(zero);
} }
static inline void gen_merge_i64(TCGv_i64 ret, TCGv_i64 x, TCGv_i64 y, TCGv_i32 cond) static inline void gen_merge_i64(TCGv_i64 ret, TCGv_i64 src1, TCGv_i64 src2,
TCGv_i32 cond)
{ {
TCGv_i64 zero = tcg_const_i64(0); TCGv_i64 zero = tcg_const_i64(0);
TCGv_i64 t0 = tcg_temp_new_i64(); TCGv_i64 t0 = tcg_temp_new_i64();
tcg_gen_extu_i32_i64(t0, cond); tcg_gen_extu_i32_i64(t0, cond);
tcg_gen_movcond_i64(TCG_COND_EQ, ret, t0, zero, x, y); tcg_gen_movcond_i64(TCG_COND_EQ, ret, t0, zero, src1, src2);
tcg_temp_free_i64(t0); tcg_temp_free_i64(t0);
tcg_temp_free_i64(zero); tcg_temp_free_i64(zero);
} }
@ -1743,9 +1731,12 @@ static void gen_alopf1_mrgc_i32(DisasContext *ctx, Instr *instr)
Src32 s2 = get_src2_i32(ctx, chan); Src32 s2 = get_src2_i32(ctx, chan);
TCGv_i32 tag = e2k_get_temp_i32(ctx); TCGv_i32 tag = e2k_get_temp_i32(ctx);
TCGv_i32 dst = e2k_get_temp_i32(ctx); TCGv_i32 dst = e2k_get_temp_i32(ctx);
TCGv_i32 t0 = tcg_temp_new_i32();
gen_tag2_i32(tag, s1.tag, s2.tag); gen_tag2_i32(tag, s1.tag, s2.tag);
gen_merge_i32(dst, s1.value, s2.value, instr->mrgc); gen_mrgc_i32(ctx, instr->chan, t0);
gen_merge_i32(dst, s1.value, s2.value, t0);
tcg_temp_free_i32(t0);
gen_al_result_i32(ctx, chan, dst, tag); gen_al_result_i32(ctx, chan, dst, tag);
} }
@ -1756,9 +1747,12 @@ static void gen_alopf1_mrgc_i64(DisasContext *ctx, Instr *instr)
Src64 s2 = get_src2_i64(ctx, chan); Src64 s2 = get_src2_i64(ctx, chan);
TCGv_i32 tag = e2k_get_temp_i32(ctx); TCGv_i32 tag = e2k_get_temp_i32(ctx);
TCGv_i64 dst = e2k_get_temp_i64(ctx); TCGv_i64 dst = e2k_get_temp_i64(ctx);
TCGv_i32 t0 = tcg_temp_new_i32();
gen_tag2_i64(tag, s1.tag, s2.tag); gen_tag2_i64(tag, s1.tag, s2.tag);
gen_merge_i64(dst, s1.value, s2.value, instr->mrgc); gen_mrgc_i32(ctx, instr->chan, t0);
gen_merge_i64(dst, s1.value, s2.value, t0);
tcg_temp_free_i32(t0);
gen_al_result_i64(ctx, chan, dst, tag); gen_al_result_i64(ctx, chan, dst, tag);
} }
@ -2155,6 +2149,7 @@ static void execute_icomb_i64(DisasContext *ctx, Instr *instr)
Src64 s3 = get_src3_i64(ctx, instr->chan); Src64 s3 = get_src3_i64(ctx, instr->chan);
TCGv_i32 tag = e2k_get_temp_i32(ctx); TCGv_i32 tag = e2k_get_temp_i32(ctx);
TCGv_i64 dst = e2k_get_temp_i64(ctx); TCGv_i64 dst = e2k_get_temp_i64(ctx);
TCGv_i32 mrgc = NULL;
gen_tag3_i64(tag, s1.tag, s2.tag, s3.tag); gen_tag3_i64(tag, s1.tag, s2.tag, s3.tag);
switch(opc1) { switch(opc1) {
@ -2184,7 +2179,9 @@ static void execute_icomb_i64(DisasContext *ctx, Instr *instr)
break; break;
case 0x0f: case 0x0f:
/* merge_{op}d */ /* merge_{op}d */
gen_merge_i64(dst, s1.value, s2.value, instr->mrgc); mrgc = tcg_temp_new_i32();
gen_mrgc_i32(ctx, instr->chan, mrgc);
gen_merge_i64(dst, s1.value, s2.value, mrgc);
break; break;
case 0x11: case 0x11:
/* add_{op}d */ /* add_{op}d */
@ -2262,7 +2259,11 @@ static void execute_icomb_i64(DisasContext *ctx, Instr *instr)
case 0x60: case 0x60:
/* {op}_merged */ /* {op}_merged */
if (ctx->version == 1) { if (ctx->version == 1) {
gen_merge_i64(dst, dst, s3.value, instr->mrgc); if (mrgc == NULL) {
mrgc = tcg_temp_new_i32();
gen_mrgc_i32(ctx, instr->chan, mrgc);
}
gen_merge_i64(dst, dst, s3.value, mrgc);
} else { } else {
e2k_tr_gen_exception(ctx, E2K_EXCP_ILLOPC); e2k_tr_gen_exception(ctx, E2K_EXCP_ILLOPC);
return; return;
@ -2333,6 +2334,10 @@ static void execute_icomb_i64(DisasContext *ctx, Instr *instr)
} }
} }
if (mrgc != NULL) {
tcg_temp_free_i32(mrgc);
}
gen_al_result_i64(ctx, instr->chan, dst, tag); gen_al_result_i64(ctx, instr->chan, dst, tag);
} }
@ -2345,6 +2350,7 @@ static void execute_icomb_i32(DisasContext *ctx, Instr *instr)
Src32 s3 = get_src3_i32(ctx, instr->chan); Src32 s3 = get_src3_i32(ctx, instr->chan);
TCGv_i32 tag = e2k_get_temp_i32(ctx); TCGv_i32 tag = e2k_get_temp_i32(ctx);
TCGv_i32 dst = e2k_get_temp_i32(ctx); TCGv_i32 dst = e2k_get_temp_i32(ctx);
TCGv_i32 mrgc = NULL;
gen_tag3_i32(tag, s1.tag, s2.tag, s3.tag); gen_tag3_i32(tag, s1.tag, s2.tag, s3.tag);
switch(opc1) { switch(opc1) {
@ -2374,7 +2380,9 @@ static void execute_icomb_i32(DisasContext *ctx, Instr *instr)
break; break;
case 0x0e: case 0x0e:
/* merge_{op}s */ /* merge_{op}s */
gen_merge_i32(dst, s1.value, s2.value, instr->mrgc); mrgc = tcg_temp_new_i32();
gen_mrgc_i32(ctx, instr->chan, mrgc);
gen_merge_i32(dst, s1.value, s2.value, mrgc);
break; break;
case 0x10: case 0x10:
/* add_{op}s */ /* add_{op}s */
@ -2452,7 +2460,11 @@ static void execute_icomb_i32(DisasContext *ctx, Instr *instr)
case 0x60: case 0x60:
/* {op}_merges */ /* {op}_merges */
if (ctx->version == 1) { if (ctx->version == 1) {
gen_merge_i32(dst, dst, s3.value, instr->mrgc); if (mrgc == NULL) {
mrgc = tcg_temp_new_i32();
gen_mrgc_i32(ctx, instr->chan, mrgc);
}
gen_merge_i32(dst, dst, s3.value, mrgc);
} else { } else {
e2k_tr_gen_exception(ctx, E2K_EXCP_ILLOPC); e2k_tr_gen_exception(ctx, E2K_EXCP_ILLOPC);
return; return;
@ -2523,6 +2535,10 @@ static void execute_icomb_i32(DisasContext *ctx, Instr *instr)
} }
} }
if (mrgc != NULL) {
tcg_temp_free_i32(mrgc);
}
gen_al_result_i32(ctx, instr->chan, dst, tag); gen_al_result_i32(ctx, instr->chan, dst, tag);
} }
@ -2587,9 +2603,13 @@ static void chan_execute(DisasContext *ctx, int chan)
const UnpackedBundle *bundle = &ctx->bundle; const UnpackedBundle *bundle = &ctx->bundle;
uint16_t rlp = find_cond(ctx, chan); uint16_t rlp = find_cond(ctx, chan);
TCGLabel *l0 = gen_new_label(); TCGLabel *l0 = gen_new_label();
Instr instr = instr_new(ctx, chan); Instr instr = { 0 };
TCGv_i64 cond = NULL; TCGv_i64 cond = NULL;
instr.chan = chan;
instr.als = ctx->bundle.als[chan];
instr.ales = ctx->bundle.ales[chan];
if (rlp != 0) { if (rlp != 0) {
TCGv_i64 t0 = tcg_temp_new_i64(); TCGv_i64 t0 = tcg_temp_new_i64();
uint8_t psrc = GET_FIELD(rlp, 0, 7); uint8_t psrc = GET_FIELD(rlp, 0, 7);