target/mips: add Octeon MTM instructions
Add the MTM0, MTM1, and MTM2 forms that load the Octeon3 multiplier operand pair from rs/rt into MPL[x] and MPL[x+3], then clear the partial products. For MPL0, also set MPL[1] to zero for backward compatibility with Octeon2 VMULU. Legacy single-source encodings have rt encoded as $zero, so the same translator path also preserves the older Octeon behavior. Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: James Hilliard <james.hilliard1@gmail.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-Id: <20260520172313.23777-19-philmd@linaro.org>
James Hilliard committed
May 8, 2026 at 10:52 UTC
41299492973e47e9bb38716f3d9d21fb870e562a
2 files changed
+39
target/mips/tcg/octeon.decode
+7
@@ -44,6 +44,13 @@ 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
+&r2 rs rt
48
+@r2 ...... rs:5 rt:5 ..... ..... ...... &r2
49
+
50
+MTM0 011100 ..... ..... 00000 00000 001000 @r2
51
+MTM1 011100 ..... ..... 00000 00000 001100 @r2
52
+MTM2 011100 ..... ..... 00000 00000 001101 @r2
53
+
54
&saa base rt
55
@saa ...... base:5 rt:5 ................ &saa
56
SAA 011100 ..... ..... 00000 00000 011000 @saa
target/mips/tcg/octeon_translate.c
+32
@@ -209,3 +209,35 @@ static bool trans_ZCB(DisasContext *ctx, arg_ZCB *a)
209
210
return true;
211
}
212
+
213
+static void octeon_zero_partial_product_state(void)
214
+{
215
+ for (int i = 0; i < OCTEON_MULTIPLIER_REGS; i++) {
216
+ tcg_gen_movi_i64(oct_p[i], 0);
217
+ }
218
+}
219
+
220
+static bool trans_mtm(DisasContext *ctx, arg_r2 *a, unsigned int index)
221
+{
222
+ /*
223
+ * Octeon3 two-source MTM forms load lane index from rs and lane index + 3
224
+ * from rt. Legacy one-source forms encode rt as $zero.
225
+ */
226
+ gen_load_gpr(oct_mpl[index], a->rs);
227
+ gen_load_gpr(oct_mpl[index + 3], a->rt);
228
+
229
+ /*
230
+ * Octeon3 clears MPL1 with a write to MPL0 so that VMULU sequences remain
231
+ * backward compatible with Octeon2.
232
+ */
233
+ if (index == 0) {
234
+ tcg_gen_movi_i64(oct_mpl[1], 0);
235
+ }
236
+
237
+ octeon_zero_partial_product_state();
238
+ return true;
239
+}
240
+
241
+TRANS(MTM0, trans_mtm, 0);
242
+TRANS(MTM1, trans_mtm, 1);
243
+TRANS(MTM2, trans_mtm, 2);