target: e2k: Impl write AL result to ctpr.

This commit is contained in:
Denis Drakhnia 2020-12-03 20:19:16 +02:00 committed by Denis Drakhnia
parent 683d96b8fa
commit b14ca9755f
2 changed files with 44 additions and 3 deletions

View File

@ -106,6 +106,8 @@ typedef enum {
AL_RESULT_REG32,
AL_RESULT_REG64,
AL_RESULT_PREG,
AL_RESULT_CTPR32,
AL_RESULT_CTPR64,
} AlResultType;
typedef struct {
@ -122,7 +124,11 @@ typedef struct {
struct {
int index;
TCGv_i64 value;
} preg;
} preg, ctpr64;
struct {
int index;
TCGv_i32 value;
} ctpr32;
};
} AlResult;

View File

@ -209,12 +209,17 @@ static inline void set_al_result_reg64_tag(DisasContext *ctx, int chan,
uint8_t arg = extract32(ctx->bundle.als[chan], 0, 8);
AlResult *res = &ctx->al_results[chan];
// TODO: %ctpr, %tst, %tc, %tcd
// TODO: %tst, %tc, %tcd
if (arg == 0xdf) { /* %empty */
res->type = AL_RESULT_NONE;
res->reg.index = NULL;
res->reg.v64 = NULL;
res->reg.tag = NULL;
} else if ((arg & 0xfc) == 0xd0 && (arg & 3) != 0) {
// TODO: check if instruction can write to ctpr
res->type = AL_RESULT_CTPR64;
res->ctpr64.index = (arg & 3) - 1;
res->ctpr64.value = value;
} else {
res->type = AL_RESULT_REG64;
res->reg.v64 = value;
@ -236,12 +241,17 @@ static inline void set_al_result_reg32_tag(DisasContext *ctx, int chan,
uint8_t arg = extract32(ctx->bundle.als[chan], 0, 8);
AlResult *res = &ctx->al_results[chan];
// TODO: %ctpr, %tst, %tc, %tcd
// TODO: %tst, %tc, %tcd
if (arg == 0xdf) { /* %empty */
res->type = AL_RESULT_NONE;
res->reg.index = NULL;
res->reg.v32 = NULL;
res->reg.tag = NULL;
} else if ((arg & 0xfc) == 0xd0 && (arg & 3) != 0) {
// TODO: check if instruction can write to ctpr
res->type = AL_RESULT_CTPR32;
res->ctpr32.index = (arg & 3) - 1;
res->ctpr32.value = value;
} else {
res->type = AL_RESULT_REG32;
res->reg.v32 = value;
@ -1746,6 +1756,31 @@ void e2k_alc_commit(DisasContext *ctx)
case AL_RESULT_PREG:
e2k_gen_store_preg(res->preg.index, res->preg.value);
break;
case AL_RESULT_CTPR32: {
TCGv_i64 ctpr = e2k_cs.ctprs[res->ctpr32.index];
TCGv_i64 t0 = tcg_temp_new_i64();
TCGv_i64 t1 = tcg_const_i64(CTPR_TAG_DISP);
assert(res->ctpr32.index < 3);
tcg_gen_extu_i32_i64(t0, res->ctpr32.value);
tcg_gen_deposit_i64(ctpr, ctpr, t0, 0, 48);
tcg_gen_deposit_i64(ctpr, ctpr, t1, CTPR_TAG_OFF,
CTPR_TAG_LEN);
tcg_temp_free_i64(t1);
tcg_temp_free_i64(t0);
break;
}
case AL_RESULT_CTPR64: {
TCGv_i64 ctpr = e2k_cs.ctprs[res->ctpr64.index];
TCGv_i64 t0 = tcg_const_i64(CTPR_TAG_DISP);
assert(res->ctpr64.index < 3);
tcg_gen_deposit_i64(ctpr, ctpr, res->ctpr64.value, 0, 48);
tcg_gen_deposit_i64(ctpr, ctpr, t0, CTPR_TAG_OFF,
CTPR_TAG_LEN);
tcg_temp_free_i64(t0);
break;
}
default:
break;
}