From: James Hilliard <[email protected]> BADDU and DMUL write their results to rd, not rt. Route writes through gen_store_gpr() so rd == $zero is handled consistently.
Reviewed-by: Richard Henderson <[email protected]> Reviewed-by: Philippe Mathieu-Daudé <[email protected]> Signed-off-by: James Hilliard <[email protected]> Signed-off-by: Philippe Mathieu-Daudé <[email protected]> Message-Id: <[email protected]> --- target/mips/tcg/octeon_translate.c | 16 +++------ tests/tcg/mips/user/isa/octeon/octeon-insns.c | 35 +++++++++++++++++++ 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/target/mips/tcg/octeon_translate.c b/target/mips/tcg/octeon_translate.c index e1f52d444aa..4dd76268350 100644 --- a/target/mips/tcg/octeon_translate.c +++ b/target/mips/tcg/octeon_translate.c @@ -45,18 +45,14 @@ static bool trans_BADDU(DisasContext *ctx, arg_BADDU *a) { TCGv_i64 t0, t1; - if (a->rt == 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); tcg_gen_add_i64(t0, t0, t1); - tcg_gen_andi_i64(cpu_gpr[a->rd], t0, 0xff); + tcg_gen_andi_i64(t0, t0, 0xff); + gen_store_gpr(t0, a->rd); return true; } @@ -64,17 +60,13 @@ static bool trans_DMUL(DisasContext *ctx, arg_DMUL *a) { TCGv_i64 t0, t1; - if (a->rt == 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); - tcg_gen_mul_i64(cpu_gpr[a->rd], t0, t1); + tcg_gen_mul_i64(t0, t0, t1); + gen_store_gpr(t0, a->rd); return true; } diff --git a/tests/tcg/mips/user/isa/octeon/octeon-insns.c b/tests/tcg/mips/user/isa/octeon/octeon-insns.c index aef23fb9465..b7610db812e 100644 --- a/tests/tcg/mips/user/isa/octeon/octeon-insns.c +++ b/tests/tcg/mips/user/isa/octeon/octeon-insns.c @@ -7,7 +7,42 @@ #include <assert.h> #include <stdint.h> +static uint64_t octeon_baddu(uint64_t rs, uint64_t rt) +{ + uint64_t rd; + + asm volatile( + "move $8, %[rs]\n\t" + "move $9, %[rt]\n\t" + ".word 0x71095028\n\t" /* baddu $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_dmul(uint64_t rs, uint64_t rt) +{ + uint64_t rd; + + asm volatile( + "move $8, %[rs]\n\t" + "move $9, %[rt]\n\t" + ".word 0x71095003\n\t" /* dmul $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); + return 0; } -- 2.53.0
