diff options
author | Philippe Mathieu-Daudé <f4bug@amsat.org> | 2021-02-13 14:43:52 +0100 |
---|---|---|
committer | Philippe Mathieu-Daudé <f4bug@amsat.org> | 2021-07-11 22:29:54 +0200 |
commit | 82fbf9fc808b94dd8c5a1aafb19818620c5c4801 (patch) | |
tree | 07f3f22386951b0728716309ccee1c495626cc49 /target | |
parent | a9ea77f2dc5ee516adb7757e266e0d1790ddbf1a (diff) |
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>
Diffstat (limited to 'target')
-rw-r--r-- | target/mips/tcg/tx79.decode | 3 | ||||
-rw-r--r-- | target/mips/tcg/tx79_translate.c | 66 |
2 files changed, 69 insertions, 0 deletions
diff --git a/target/mips/tcg/tx79.decode b/target/mips/tcg/tx79.decode index 98f21d33e3..cfe721755c 100644 --- a/target/mips/tcg/tx79.decode +++ b/target/mips/tcg/tx79.decode @@ -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 diff --git a/target/mips/tcg/tx79_translate.c b/target/mips/tcg/tx79_translate.c index c4656a4c21..8dd510c271 100644 --- a/target/mips/tcg/tx79_translate.c +++ b/target/mips/tcg/tx79_translate.c @@ -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) * ------------------- |