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
}