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_REG32,
AL_RESULT_REG64, AL_RESULT_REG64,
AL_RESULT_PREG, AL_RESULT_PREG,
AL_RESULT_CTPR32,
AL_RESULT_CTPR64,
} AlResultType; } AlResultType;
typedef struct { typedef struct {
@ -122,7 +124,11 @@ typedef struct {
struct { struct {
int index; int index;
TCGv_i64 value; TCGv_i64 value;
} preg; } preg, ctpr64;
struct {
int index;
TCGv_i32 value;
} ctpr32;
}; };
} AlResult; } 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); uint8_t arg = extract32(ctx->bundle.als[chan], 0, 8);
AlResult *res = &ctx->al_results[chan]; AlResult *res = &ctx->al_results[chan];
// TODO: %ctpr, %tst, %tc, %tcd // TODO: %tst, %tc, %tcd
if (arg == 0xdf) { /* %empty */ if (arg == 0xdf) { /* %empty */
res->type = AL_RESULT_NONE; res->type = AL_RESULT_NONE;
res->reg.index = NULL; res->reg.index = NULL;
res->reg.v64 = NULL; res->reg.v64 = NULL;
res->reg.tag = 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 { } else {
res->type = AL_RESULT_REG64; res->type = AL_RESULT_REG64;
res->reg.v64 = value; 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); uint8_t arg = extract32(ctx->bundle.als[chan], 0, 8);
AlResult *res = &ctx->al_results[chan]; AlResult *res = &ctx->al_results[chan];
// TODO: %ctpr, %tst, %tc, %tcd // TODO: %tst, %tc, %tcd
if (arg == 0xdf) { /* %empty */ if (arg == 0xdf) { /* %empty */
res->type = AL_RESULT_NONE; res->type = AL_RESULT_NONE;
res->reg.index = NULL; res->reg.index = NULL;
res->reg.v32 = NULL; res->reg.v32 = NULL;
res->reg.tag = 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 { } else {
res->type = AL_RESULT_REG32; res->type = AL_RESULT_REG32;
res->reg.v32 = value; res->reg.v32 = value;
@ -1746,6 +1756,31 @@ void e2k_alc_commit(DisasContext *ctx)
case AL_RESULT_PREG: case AL_RESULT_PREG:
e2k_gen_store_preg(res->preg.index, res->preg.value); e2k_gen_store_preg(res->preg.index, res->preg.value);
break; 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: default:
break; break;
} }