@samitouri / QOSamiQemu / commits / dedb985c47

target/mips: fix Octeon arithmetic destination handling

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 <richard.henderson@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: James Hilliard <james.hilliard1@gmail.com> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-Id: <20260520172313.23777-7-philmd@linaro.org>

James Hilliard committed Apr 20, 2026 at 21:27 UTC dedb985c473a61929f4adac9c271c7578228a10f
2 files changed +39 -12
target/mips/tcg/octeon_translate.c
+4 -12
@@ -45,18 +45,14 @@ static bool trans_BADDU(DisasContext *ctx, arg_BADDU *a)
45 {
46 TCGv_i64 t0, t1;
47
48 - if (a->rt == 0) {
49 - /* nop */
50 - return true;
51 - }
52 -
48 t0 = tcg_temp_new_i64();
49 t1 = tcg_temp_new_i64();
50 gen_load_gpr(t0, a->rs);
51 gen_load_gpr(t1, a->rt);
52
53 tcg_gen_add_i64(t0, t0, t1);
59 - tcg_gen_andi_i64(cpu_gpr[a->rd], t0, 0xff);
54 + tcg_gen_andi_i64(t0, t0, 0xff);
55 + gen_store_gpr(t0, a->rd);
56 return true;
57 }
58
@@ -64,17 +60,13 @@ static bool trans_DMUL(DisasContext *ctx, arg_DMUL *a)
60 {
61 TCGv_i64 t0, t1;
62
67 - if (a->rt == 0) {
68 - /* nop */
69 - return true;
70 - }
71 -
63 t0 = tcg_temp_new_i64();
64 t1 = tcg_temp_new_i64();
65 gen_load_gpr(t0, a->rs);
66 gen_load_gpr(t1, a->rt);
67
77 - tcg_gen_mul_i64(cpu_gpr[a->rd], t0, t1);
68 + tcg_gen_mul_i64(t0, t0, t1);
69 + gen_store_gpr(t0, a->rd);
70 return true;
71 }
72
tests/tcg/mips/user/isa/octeon/octeon-insns.c
+35
@@ -7,7 +7,42 @@
7 #include <assert.h>
8 #include <stdint.h>
9
10 +static uint64_t octeon_baddu(uint64_t rs, uint64_t rt)
11 +{
12 + uint64_t rd;
13 +
14 + asm volatile(
15 + "move $8, %[rs]\n\t"
16 + "move $9, %[rt]\n\t"
17 + ".word 0x71095028\n\t" /* baddu $10, $8, $9 */
18 + "move %[rd], $10\n\t"
19 + : [rd] "=r" (rd)
20 + : [rs] "r" (rs), [rt] "r" (rt)
21 + : "$8", "$9", "$10");
22 +
23 + return rd;
24 +}
25 +
26 +static uint64_t octeon_dmul(uint64_t rs, uint64_t rt)
27 +{
28 + uint64_t rd;
29 +
30 + asm volatile(
31 + "move $8, %[rs]\n\t"
32 + "move $9, %[rt]\n\t"
33 + ".word 0x71095003\n\t" /* dmul $10, $8, $9 */
34 + "move %[rd], $10\n\t"
35 + : [rd] "=r" (rd)
36 + : [rs] "r" (rs), [rt] "r" (rt)
37 + : "$8", "$9", "$10");
38 +
39 + return rd;
40 +}
41 +
42 int main(void)
43 {
44 + assert(octeon_baddu(0x123, 0x0f0) == 0x13);
45 + assert(octeon_dmul(0x12345678, 0x10) == 0x123456780);
46 +
47 return 0;
48 }