target/mips/tx79: Introduce PCEQ* opcodes (Parallel Compare for Equal)

Introduce the 'Parallel Compare for Equal' opcodes:

 - PCEQB (Parallel Compare for Equal Byte)
 - PCEQH (Parallel Compare for Equal Halfword)
 - PCEQW (Parallel Compare for Equal Word)

Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20210309145653.743937-14-f4bug@amsat.org>
This commit is contained in:
Philippe Mathieu-Daudé 2021-02-13 14:43:52 +01:00
parent a9ea77f2dc
commit 82fbf9fc80
2 changed files with 69 additions and 0 deletions

View file

@ -40,6 +40,9 @@ PEXTLB 011100 ..... ..... ..... 11010 001000 @rs_rt_rd
# MMI1
PCEQW 011100 ..... ..... ..... 00010 101000 @rs_rt_rd
PCEQH 011100 ..... ..... ..... 00110 101000 @rs_rt_rd
PCEQB 011100 ..... ..... ..... 01010 101000 @rs_rt_rd
PEXTUW 011100 ..... ..... ..... 10010 101000 @rs_rt_rd
# MMI2

View file

@ -237,6 +237,72 @@ static bool trans_PNOR(DisasContext *ctx, arg_rtype *a)
* PCEQW rd, rs, rt Parallel Compare for Equal Word
*/
static bool trans_parallel_compare(DisasContext *ctx, arg_rtype *a,
TCGCond cond, unsigned wlen)
{
TCGv_i64 c0, c1, ax, bx, t0, t1, t2;
if (a->rd == 0) {
/* nop */
return true;
}
c0 = tcg_const_tl(0);
c1 = tcg_const_tl(0xffffffff);
ax = tcg_temp_new_i64();
bx = tcg_temp_new_i64();
t0 = tcg_temp_new_i64();
t1 = tcg_temp_new_i64();
t2 = tcg_temp_new_i64();
/* Lower half */
gen_load_gpr(ax, a->rs);
gen_load_gpr(bx, a->rt);
for (int i = 0; i < (64 / wlen); i++) {
tcg_gen_sextract_i64(t0, ax, wlen * i, wlen);
tcg_gen_sextract_i64(t1, bx, wlen * i, wlen);
tcg_gen_movcond_i64(cond, t2, t1, t0, c1, c0);
tcg_gen_deposit_i64(cpu_gpr[a->rd], cpu_gpr[a->rd], t2, wlen * i, wlen);
}
/* Upper half */
gen_load_gpr_hi(ax, a->rs);
gen_load_gpr_hi(bx, a->rt);
for (int i = 0; i < (64 / wlen); i++) {
tcg_gen_sextract_i64(t0, ax, wlen * i, wlen);
tcg_gen_sextract_i64(t1, bx, wlen * i, wlen);
tcg_gen_movcond_i64(cond, t2, t1, t0, c1, c0);
tcg_gen_deposit_i64(cpu_gpr_hi[a->rd], cpu_gpr_hi[a->rd], t2, wlen * i, wlen);
}
tcg_temp_free(t2);
tcg_temp_free(t1);
tcg_temp_free(t0);
tcg_temp_free(bx);
tcg_temp_free(ax);
tcg_temp_free(c1);
tcg_temp_free(c0);
return true;
}
/* Parallel Compare for Equal Byte */
static bool trans_PCEQB(DisasContext *ctx, arg_rtype *a)
{
return trans_parallel_compare(ctx, a, TCG_COND_EQ, 8);
}
/* Parallel Compare for Equal Halfword */
static bool trans_PCEQH(DisasContext *ctx, arg_rtype *a)
{
return trans_parallel_compare(ctx, a, TCG_COND_EQ, 16);
}
/* Parallel Compare for Equal Word */
static bool trans_PCEQW(DisasContext *ctx, arg_rtype *a)
{
return trans_parallel_compare(ctx, a, TCG_COND_EQ, 32);
}
/*
* LZC (1 instruction)
* -------------------