From: James Hilliard
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
Signed-off-by: James Hilliard
Signed-off-by: Richard Henderson
Signed-off-by: Philippe Mathieu-Daudé
---
target/mips/tcg/octeon.decode | 7 +++
target/mips/tcg/octeon_translate.c | 32 ++
2 files changed, 39 insertions(+)
diff --git a/target/mips/tcg/octeon.decode b/target/mips/tcg/octeon.decode
index 01ed3b50beb..5139543b153 100644
--- a/target/mips/tcg/octeon.decode
+++ b/target/mips/tcg/octeon.decode
@@ -44,6 +44,13 @@ SNE 011100 . . . 0 101011 @r3
SEQI 011100 rs:5 rt:5 imm:s10 101110 &cmpi
SNEI 011100 rs:5 rt:5 imm:s10 10 &cmpi
+&r2 rs rt
+@r2 .. rs:5 rt:5 . . .. &r2
+
+MTM0 011100 . . 0 0 001000 @r2
+MTM1 011100 . . 0 0 001100 @r2
+MTM2 011100 . . 0 0 001101 @r2
+
&saa base rt
@saa .. base:5 rt:5 &saa
SAA 011100 . . 0 0 011000 @saa
diff --git a/target/mips/tcg/octeon_translate.c
b/target/mips/tcg/octeon_translate.c
index b5ebad98048..aae6e9811c8 100644
--- a/target/mips/tcg/octeon_translate.c
+++ b/target/mips/tcg/octeon_translate.c
@@ -210,3 +210,35 @@ TRANS(LHUX, trans_lx, MO_UW);
TRANS(LWX, trans_lx, MO_SL);
TRANS(LWUX, trans_lx, MO_UL);
TRANS(LDX, trans_lx, MO_UQ);
+
+static void octeon_zero_partial_product_state(void)
+{
+for (int i = 0; i < OCTEON_MULTIPLIER_REGS; i++) {
+tcg_gen_movi_i64(oct_p[i], 0);
+}
+}
+
+static bool trans_mtm(DisasContext *ctx, arg_r2 *a, unsigned int index)
+{
+/*
+ * Octeon3 two-source MTM forms load lane index from rs and lane index + 3
+ * from rt. Legacy one-source forms encode rt as $zero.
+ */
+gen_load_gpr(oct_mpl[index], a->rs);
+gen_load_gpr(oct_mpl[index + 3], a->rt);
+
+/*
+ * Octeon3 clears MPL1 with MPL0 so that VMULU sequences remain
+ * backward compatible with Octeon2.
+ */
+if (index == 0) {
+tcg_gen_movi_i64(oct_mpl[1], 0);
+}
+
+octeon_zero_partial_product_state();
+return true;
+}
+
+TRANS(MTM0, trans_mtm, 0);
+TRANS(MTM1, trans_mtm, 1);
+TRANS(MTM2, trans_mtm, 2);
--
2.53.0