target: e2k: Add gettag{s,d} instrs.

This commit is contained in:
Denis Drakhnia 2020-12-02 17:39:16 +02:00 committed by Denis Drakhnia
parent f817f7e354
commit f0390fa97b
3 changed files with 79 additions and 33 deletions

View File

@ -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);

View File

@ -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 {

View File

@ -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?