mirror of
https://gitlab.com/qemu-project/qemu
synced 2024-09-06 18:05:37 +00:00
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:
parent
a9ea77f2dc
commit
82fbf9fc80
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
* -------------------
|
||||
|
|
Loading…
Reference in a new issue