From f0390fa97b0be931708b64a9b9e487411de806be Mon Sep 17 00:00:00 2001 From: Denis Drakhnya Date: Wed, 2 Dec 2020 17:39:16 +0200 Subject: [PATCH] target: e2k: Add gettag{s,d} instrs. --- target/e2k/translate.h | 61 ++++++++++++++++++------------------ target/e2k/translate/alc.c | 44 ++++++++++++++++++++++++-- target/e2k/translate/state.c | 7 ++++- 3 files changed, 79 insertions(+), 33 deletions(-) diff --git a/target/e2k/translate.h b/target/e2k/translate.h index 8505cc62b3..b1f6eac021 100644 --- a/target/e2k/translate.h +++ b/target/e2k/translate.h @@ -297,36 +297,6 @@ static inline void e2k_gen_lcntex(TCGv_i32 ret) tcg_temp_free_i32(t0); } -void e2k_gen_store_preg(int idx, TCGv_i64 val); - -void e2k_gen_reg_tag_read(TCGv_i32 ret, TCGv_i32 idx); -void e2k_gen_reg_tag_write_i64(TCGv_i32 value, TCGv_i32 idx); -void e2k_gen_reg_tag_write_i32(TCGv_i32 value, TCGv_i32 idx); - -static inline void e2k_gen_reg_tag_writei_i64(int value, TCGv_i32 idx) -{ - TCGv_i32 t0 = tcg_const_i32(value); - e2k_gen_reg_tag_write_i64(t0, idx); - tcg_temp_free_i32(t0); -} - -static inline void e2k_gen_reg_tag_writei_i32(int value, TCGv_i32 idx) -{ - TCGv_i32 t0 = tcg_const_i32(value); - e2k_gen_reg_tag_write_i32(t0, idx); - tcg_temp_free_i32(t0); -} - -static inline void e2k_gen_reg_tag_extract_lo(TCGv_i32 ret, TCGv_i32 tags) -{ - tcg_gen_andi_i32(ret, tags, GEN_MASK(0, E2K_TAG_SIZE)); -} - -static inline void e2k_gen_reg_tag_extract_hi(TCGv_i32 ret, TCGv_i32 tags) -{ - tcg_gen_shri_i32(ret, tags, E2K_TAG_SIZE); -} - static inline bool is_load_chan(int chan) { switch(chan) { @@ -365,6 +335,37 @@ static inline bool is_div_chan(int chan) { return chan == 5; } +void e2k_gen_store_preg(int idx, TCGv_i64 val); + +void e2k_gen_reg_tag_read_i64(TCGv_i32 ret, TCGv_i32 idx); +void e2k_gen_reg_tag_read_i32(TCGv_i32 ret, TCGv_i32 idx); +void e2k_gen_reg_tag_write_i64(TCGv_i32 value, TCGv_i32 idx); +void e2k_gen_reg_tag_write_i32(TCGv_i32 value, TCGv_i32 idx); + +static inline void e2k_gen_reg_tag_writei_i64(int value, TCGv_i32 idx) +{ + TCGv_i32 t0 = tcg_const_i32(value); + e2k_gen_reg_tag_write_i64(t0, idx); + tcg_temp_free_i32(t0); +} + +static inline void e2k_gen_reg_tag_writei_i32(int value, TCGv_i32 idx) +{ + TCGv_i32 t0 = tcg_const_i32(value); + e2k_gen_reg_tag_write_i32(t0, idx); + tcg_temp_free_i32(t0); +} + +static inline void e2k_gen_reg_tag_extract_lo(TCGv_i32 ret, TCGv_i32 tags) +{ + tcg_gen_andi_i32(ret, tags, GEN_MASK(0, E2K_TAG_SIZE)); +} + +static inline void e2k_gen_reg_tag_extract_hi(TCGv_i32 ret, TCGv_i32 tags) +{ + tcg_gen_shri_i32(ret, tags, E2K_TAG_SIZE); +} + void e2k_gen_reg_tag_check_i64(TCGv_i32 ret, TCGv_i32 tag); void e2k_gen_reg_tag_check_i32(TCGv_i32 ret, TCGv_i32 tag); diff --git a/target/e2k/translate/alc.c b/target/e2k/translate/alc.c index 5967099d56..d2b246ed15 100644 --- a/target/e2k/translate/alc.c +++ b/target/e2k/translate/alc.c @@ -33,7 +33,7 @@ static inline void gen_reg_i64(DisasContext *ctx, Src64 *ret, uint8_t arg) gen_reg_index(t0, arg); ret->tag = e2k_get_temp_i32(ctx); ret->value = e2k_get_temp_i64(ctx); - e2k_gen_reg_tag_read(ret->tag, t0); + e2k_gen_reg_tag_read_i64(ret->tag, t0); e2k_gen_reg_read_i64(ret->value, t0); tcg_temp_free_i32(t0); @@ -46,7 +46,7 @@ static inline void gen_reg_i32(DisasContext *ctx, Src32 *ret, uint8_t arg) gen_reg_index(t0, arg); ret->tag = e2k_get_temp_i32(ctx); ret->value = e2k_get_temp_i32(ctx); - e2k_gen_reg_tag_read(ret->tag, t0); + e2k_gen_reg_tag_read_i32(ret->tag, t0); e2k_gen_reg_read_i32(ret->value, t0); tcg_temp_free_i32(t0); @@ -734,6 +734,34 @@ static inline void gen_sdivs(TCGv_i32 ret, TCGv_i32 ret_tag, bool sm, gen_set_label(l0); } +static inline void gen_gettag_i64(DisasContext *ctx, int chan) +{ + Src64 s2 = get_src2_i64(ctx, chan); + TCGv_i64 dst = e2k_get_temp_i64(ctx); + + if (s2.tag != NULL) { + tcg_gen_extu_i32_i64(dst, s2.tag); + } else { + tcg_gen_movi_i64(dst, 0); + } + + set_al_result_reg64(ctx, chan, dst); +} + +static inline void gen_gettag_i32(DisasContext *ctx, int chan) +{ + Src32 s2 = get_src2_i32(ctx, chan); + TCGv_i32 dst = e2k_get_temp_i32(ctx); + + if (s2.tag != NULL) { + tcg_gen_mov_i32(dst, s2.tag); + } else { + tcg_gen_movi_i32(dst, 0); + } + + set_al_result_reg32(ctx, chan, dst); +} + static inline void gen_puttag_i64(DisasContext *ctx, int chan) { bool sm = extract32(ctx->bundle.als[chan], 31, 1); @@ -1297,6 +1325,18 @@ static void execute_ext1_25(DisasContext *ctx, int chan) uint8_t opc = GET_FIELD(ctx->bundle.als[chan], 24, 7); switch(opc) { + case 0x08: if (chan == 2 || chan == 5) { + gen_gettag_i32(ctx, chan); /* gettags */ + } else { + e2k_tr_gen_exception(ctx, E2K_EXCP_ILLOPC); + } + break; + case 0x09: if (chan == 2 || chan == 5) { + gen_gettag_i64(ctx, chan); /* gettagd */ + } else { + e2k_tr_gen_exception(ctx, E2K_EXCP_ILLOPC); + } + break; case 0x0a: if (chan == 2 || chan == 5) { gen_puttag_i32(ctx, chan); /* puttags */ } else { diff --git a/target/e2k/translate/state.c b/target/e2k/translate/state.c index ec1b177138..64f249a01f 100644 --- a/target/e2k/translate/state.c +++ b/target/e2k/translate/state.c @@ -137,11 +137,16 @@ static inline void gen_reg_tags_read(TCGv_i32 ret, TCGv_i32 idx, int len) tcg_temp_free_i64(t4); } -void e2k_gen_reg_tag_read(TCGv_i32 ret, TCGv_i32 idx) +void e2k_gen_reg_tag_read_i64(TCGv_i32 ret, TCGv_i32 idx) { gen_reg_tags_read(ret, idx, E2K_REG_TAGS_SIZE); } +void e2k_gen_reg_tag_read_i32(TCGv_i32 ret, TCGv_i32 idx) +{ + gen_reg_tags_read(ret, idx, E2K_TAG_SIZE); +} + static inline void gen_tag_check(TCGv_i32 ret, TCGv_i32 tag) { // FIXME: what CPU does if tag is greater than 1?