From: James Hilliard <[email protected]> Decode the equality and inequality forms as explicit SEQ/SNE instructions rather than using shared generated SEQNE entries.
The explicit decoder names match the architectural mnemonics, which makes the translator entry points and trace/debug output easier to correlate with the instruction set. Reviewed-by: Richard Henderson <[email protected]> Signed-off-by: James Hilliard <[email protected]> Reviewed-by: Philippe Mathieu-Daudé <[email protected]> [PMD: Split SEQNE (this patch) vs SEQNEI] Signed-off-by: Philippe Mathieu-Daudé <[email protected]> Message-Id: <[email protected]> --- target/mips/tcg/octeon.decode | 3 +- target/mips/tcg/octeon_translate.c | 25 +++++++------ tests/tcg/mips/user/isa/octeon/octeon-insns.c | 36 +++++++++++++++++++ 3 files changed, 52 insertions(+), 12 deletions(-) diff --git a/target/mips/tcg/octeon.decode b/target/mips/tcg/octeon.decode index 102a05860df..2c54901f77e 100644 --- a/target/mips/tcg/octeon.decode +++ b/target/mips/tcg/octeon.decode @@ -38,7 +38,8 @@ DMUL 011100 ..... ..... ..... 00000 000011 @r3 EXTS 011100 ..... ..... ..... ..... 11101 . @bitfield CINS 011100 ..... ..... ..... ..... 11001 . @bitfield POP 011100 rs:5 00000 rd:5 00000 10110 dw:1 -SEQNE 011100 rs:5 rt:5 rd:5 00000 10101 ne:1 +SEQ 011100 ..... ..... ..... 00000 101010 @r3 +SNE 011100 ..... ..... ..... 00000 101011 @r3 SEQNEI 011100 rs:5 rt:5 imm:s10 10111 ne:1 &lx base index rd diff --git a/target/mips/tcg/octeon_translate.c b/target/mips/tcg/octeon_translate.c index b7531653e58..dfbb55e3fc3 100644 --- a/target/mips/tcg/octeon_translate.c +++ b/target/mips/tcg/octeon_translate.c @@ -106,29 +106,32 @@ static bool trans_POP(DisasContext *ctx, arg_POP *a) return true; } -static bool trans_SEQNE(DisasContext *ctx, arg_SEQNE *a) +static bool do_seq_sne(DisasContext *ctx, const arg_decode_ext_octeon1 *a, + TCGCond cond) { TCGv_i64 t0, t1; - if (a->rd == 0) { - /* nop */ - return true; - } - t0 = tcg_temp_new_i64(); t1 = tcg_temp_new_i64(); gen_load_gpr(t0, a->rs); gen_load_gpr(t1, a->rt); - if (a->ne) { - tcg_gen_setcond_i64(TCG_COND_NE, cpu_gpr[a->rd], t1, t0); - } else { - tcg_gen_setcond_i64(TCG_COND_EQ, cpu_gpr[a->rd], t1, t0); - } + tcg_gen_setcond_i64(cond, t0, t1, t0); + gen_store_gpr(t0, a->rd); return true; } +static bool trans_SEQ(DisasContext *ctx, arg_SEQ *a) +{ + return do_seq_sne(ctx, a, TCG_COND_EQ); +} + +static bool trans_SNE(DisasContext *ctx, arg_SNE *a) +{ + return do_seq_sne(ctx, a, TCG_COND_NE); +} + static bool trans_SEQNEI(DisasContext *ctx, arg_SEQNEI *a) { TCGv_i64 t0; diff --git a/tests/tcg/mips/user/isa/octeon/octeon-insns.c b/tests/tcg/mips/user/isa/octeon/octeon-insns.c index f406726fc11..3c3802ebfee 100644 --- a/tests/tcg/mips/user/isa/octeon/octeon-insns.c +++ b/tests/tcg/mips/user/isa/octeon/octeon-insns.c @@ -54,11 +54,47 @@ static uint64_t octeon_dpop(uint64_t rs) return rd; } +static uint64_t octeon_seq(uint64_t rs, uint64_t rt) +{ + uint64_t rd; + + asm volatile( + "move $8, %[rs]\n\t" + "move $9, %[rt]\n\t" + ".word 0x7109502a\n\t" /* seq $10, $8, $9 */ + "move %[rd], $10\n\t" + : [rd] "=r" (rd) + : [rs] "r" (rs), [rt] "r" (rt) + : "$8", "$9", "$10"); + + return rd; +} + +static uint64_t octeon_sne(uint64_t rs, uint64_t rt) +{ + uint64_t rd; + + asm volatile( + "move $8, %[rs]\n\t" + "move $9, %[rt]\n\t" + ".word 0x7109502b\n\t" /* sne $10, $8, $9 */ + "move %[rd], $10\n\t" + : [rd] "=r" (rd) + : [rs] "r" (rs), [rt] "r" (rt) + : "$8", "$9", "$10"); + + return rd; +} + int main(void) { assert(octeon_baddu(0x123, 0x0f0) == 0x13); assert(octeon_dmul(0x12345678, 0x10) == 0x123456780); assert(octeon_dpop(0xf0f0f0f0f0f0f0f0ULL) == 32); + assert(octeon_seq(0xabc, 0xabc) == 1); + assert(octeon_seq(0xabc, 0xdef) == 0); + assert(octeon_sne(0xabc, 0xabc) == 0); + assert(octeon_sne(0xabc, 0xdef) == 1); return 0; } -- 2.53.0
