@samitouri / QOSamiQemu / commits / 76f8ab8aed

target/mips: add Octeon V3MULU instruction

V3MULU extends VMULU across the full Octeon3 multiplier state, adding rt and queued partial products. Return the low result while shifting the remaining accumulated limbs back into P[0] through P[5]. 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> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-Id: <20260520172313.23777-23-philmd@linaro.org>

James Hilliard committed May 8, 2026 at 10:56 UTC 76f8ab8aeda5aabde1120a055b2647336275b171
2 files changed +41
target/mips/tcg/octeon.decode
+1
@@ -57,6 +57,7 @@ MTP2 011100 ..... ..... 00000 00000 001011 @r2
57
58 VMULU 011100 ..... ..... ..... 00000 001111 @r3
59 VMM0 011100 ..... ..... ..... 00000 010000 @r3
60 +V3MULU 011100 ..... ..... ..... 00000 010001 @r3
61
62 &saa base rt
63 @saa ...... base:5 rt:5 ................ &saa
target/mips/tcg/octeon_translate.c
+40
@@ -315,3 +315,43 @@ static bool trans_VMM0(DisasContext *ctx, arg_VMM0 *a)
315 octeon_zero_partial_product_state();
316 return true;
317 }
318 +
319 +static bool trans_V3MULU(DisasContext *ctx, arg_V3MULU *a)
320 +{
321 + TCGv_i64 x[7], y[7], z[7];
322 + TCGv_i64 tmp = tcg_temp_new_i64();
323 +
324 + for (int i = 0; i < 7; ++i) {
325 + z[i] = tcg_temp_new_i64();
326 + y[i] = tcg_temp_new_i64();
327 + }
328 + memcpy(&x[0], z, 6 * sizeof(TCGv_i64));
329 + x[6] = tcg_constant_i64(0);
330 +
331 + /*
332 + * Z = rs * mpl -- 64x384->448 bit multiply
333 + * Compute even partial products into X and odd partial products into Y.
334 + * Include RT into the odd partial products, which are 0 in bits [63:0].
335 + */
336 + gen_load_gpr(tmp, a->rs);
337 + gen_load_gpr(y[0], a->rt);
338 + for (int i = 0; i < 6; i += 2) {
339 + tcg_gen_mulu2_i64(x[i + 0], x[i + 1], tmp, oct_mpl[i]);
340 + tcg_gen_mulu2_i64(y[i + 1], y[i + 2], tmp, oct_mpl[i + 1]);
341 + }
342 +
343 + /* Sum even and odd to produce final product, plus rt. */
344 + tcg_gen_addN_i64(7, z, x, y);
345 +
346 + /* X == (0 : p5 : p4 : p3 : p2 : p1 : p0) -- x[6] is still 0 */
347 + memcpy(&x[0], oct_p, 6 * sizeof(TCGv_i64));
348 +
349 + /* Y == (p5 : p4 : p3 : p2 : p1 : p0 : tmp) */
350 + memcpy(&y[1], oct_p, 6 * sizeof(TCGv_i64));
351 + y[0] = tmp;
352 +
353 + /* (p* : rd) = (0 : p*) + (rs * mpl + rt) */
354 + tcg_gen_addN_i64(7, y, x, z);
355 + gen_store_gpr(tmp, a->rd);
356 + return true;
357 +}