MTP0 loads the low Octeon3 partial-product pair from rs/rt into P[0] and P[3] and sets P[1] to zero. Model the architecturally unpredictable P[2], P[4], and P[5] lanes as zero for deterministic emulation.
Legacy single-source encodings have rt encoded as $zero, so the same translator path also preserves the older Octeon behavior. Add the translator storage path so subsequent VMULU/VMM0/V3MULU operations can consume guest-managed partial products. Signed-off-by: James Hilliard <[email protected]> --- Changes v2 -> v3: - Split MTP0 out of the combined Octeon arithmetic and memory instruction patch. (requested by Richard Henderson) Changes v3 -> v4: - Keep the Octeon3 two-source rt high-lane operand and document that legacy one-source MTP encodings use rt == $zero. Changes v5 -> v6: - Zero P1 and model P2/P4/P5 as zero after checking the CN71XX register-state table and description. --- target/mips/tcg/octeon.decode | 1 + target/mips/tcg/octeon_translate.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/target/mips/tcg/octeon.decode b/target/mips/tcg/octeon.decode index bf1dab61e1..59ab7401ab 100644 --- a/target/mips/tcg/octeon.decode +++ b/target/mips/tcg/octeon.decode @@ -45,6 +45,7 @@ SEQI 011100 rs:5 rt:5 imm:s10 101110 &cmpi SNEI 011100 rs:5 rt:5 imm:s10 101111 &cmpi &r2 rs rt MTM0 011100 rs:5 rt:5 00000 00000 001000 &r2 +MTP0 011100 rs:5 rt:5 00000 00000 001001 &r2 &saa base rt @saa ...... base:5 rt:5 ................ &saa diff --git a/target/mips/tcg/octeon_translate.c b/target/mips/tcg/octeon_translate.c index 4507f8a5bc..88f64e791d 100644 --- a/target/mips/tcg/octeon_translate.c +++ b/target/mips/tcg/octeon_translate.c @@ -254,6 +254,33 @@ static bool trans_mtm(DisasContext *ctx, arg_r2 *a, unsigned int index) return true; } +static bool trans_mtp(DisasContext *ctx, arg_r2 *a, unsigned int index) +{ + TCGv_i64 value = tcg_temp_new_i64(); + + /* + * Octeon3 two-source MTP forms load lane index from rs and lane index + 3 + * from rt. Legacy one-source forms encode rt as $zero. + */ + gen_load_gpr(value, a->rs); + octeon_store_p(index, value); + gen_load_gpr(value, a->rt); + octeon_store_p(index + 3, value); + if (index == 0) { + /* + * The hardware description and register-state table define P1 as zero; + * model P2/P4/P5 as zero for deterministic emulation. + */ + TCGv_i64 zero = tcg_constant_i64(0); + + octeon_store_p(1, zero); + octeon_store_p(2, zero); + octeon_store_p(4, zero); + octeon_store_p(5, zero); + } + return true; +} + TRANS(SAA, trans_saa, MO_UL); TRANS(SAAD, trans_saa, MO_UQ); TRANS(LBX, trans_lx, MO_SB); @@ -264,3 +291,4 @@ TRANS(LWX, trans_lx, MO_SL); TRANS(LWUX, trans_lx, MO_UL); TRANS(LDX, trans_lx, MO_UQ); TRANS(MTM0, trans_mtm, 0); +TRANS(MTP0, trans_mtp, 0); -- 2.54.0
