target/mips: add Octeon SAA instruction
SAA atomically adds rt to the naturally aligned 32-bit word at base and discards the old memory value. Implement the common SAA/SAAD translator with TCG atomic_fetch_add_i64. The MemOp selects the word or doubleword transaction size. QEMU only has one Octeon CPU model today, so keep SAA/SAAD under the existing Octeon instruction feature bucket instead of adding a finer-grained Octeon+ feature bit. Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: James Hilliard <james.hilliard1@gmail.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-Id: <20260520172313.23777-14-philmd@linaro.org>
James Hilliard committed
May 8, 2026 at 10:51 UTC
818272ac89ca8a98f930d4759762765dc12349bd
2 files changed
+19
target/mips/tcg/octeon.decode
+4
@@ -44,6 +44,10 @@ SNE 011100 ..... ..... ..... 00000 101011 @r3
44
SEQI 011100 rs:5 rt:5 imm:s10 101110 &cmpi
45
SNEI 011100 rs:5 rt:5 imm:s10 101111 &cmpi
46
47
+&saa base rt
48
+@saa ...... base:5 rt:5 ................ &saa
49
+SAA 011100 ..... ..... 00000 00000 011000 @saa
50
+
51
&lx base index rd
52
@lx ...... base:5 index:5 rd:5 ...... ..... &lx
53
LWX 011111 ..... ..... ..... 00000 001010 @lx
target/mips/tcg/octeon_translate.c
+15
@@ -168,3 +168,18 @@ TRANS(LHUX, trans_lx, MO_UW);
168
TRANS(LWX, trans_lx, MO_SL);
169
TRANS(LWUX, trans_lx, MO_UL);
170
TRANS(LDX, trans_lx, MO_UQ);
171
+
172
+static bool trans_saa(DisasContext *ctx, arg_saa *a, MemOp mop)
173
+{
174
+ TCGv_i64 addr = tcg_temp_new_i64();
175
+ TCGv_i64 value = tcg_temp_new_i64();
176
+ TCGv_i64 old = tcg_temp_new_i64();
177
+ MemOp amo = mo_endian(ctx) | mop | MO_ALIGN;
178
+
179
+ gen_base_offset_addr(ctx, addr, a->base, 0);
180
+ gen_load_gpr(value, a->rt);
181
+ tcg_gen_atomic_fetch_add_i64(old, addr, value, ctx->mem_idx, amo);
182
+ return true;
183
+}
184
+
185
+TRANS(SAA, trans_saa, MO_32);