Commit 613d9084db for qemu.org
commit 613d9084dbf0c597b9d7d862e2da6ff69e6258ea
Author: Richard Henderson <richard.henderson@linaro.org>
Date: Mon Sep 14 12:59:31 2026 -1000
target/mips/tcg: Use gen_mxu_logic for gen_mxu_S32MAX_S32MIN
Split S32MAX, S32MIN to separate functions.
Fixes a bug in that "0" was passed in one of the zero reg cases,
aka NULL, instead of a proper zero constant.
Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
diff --git a/target/mips/tcg/mxu_translate.c b/target/mips/tcg/mxu_translate.c
index 3f8acfcdb8..4b2c264f03 100644
--- a/target/mips/tcg/mxu_translate.c
+++ b/target/mips/tcg/mxu_translate.c
@@ -2045,45 +2045,14 @@ static void gen_mxu_q16sxxv(DisasContext *ctx, bool right, bool arithmetic)
* Update XRa with the minimum of signed 32-bit integers contained
* in XRb and XRc.
*/
-static void gen_mxu_S32MAX_S32MIN(DisasContext *ctx)
+static void gen_mxu_S32MAX(DisasContext *ctx)
{
- uint32_t pad, opc, XRc, XRb, XRa;
-
- pad = extract32(ctx->opcode, 21, 5);
- opc = extract32(ctx->opcode, 18, 3);
- XRc = extract32(ctx->opcode, 14, 4);
- XRb = extract32(ctx->opcode, 10, 4);
- XRa = extract32(ctx->opcode, 6, 4);
+ gen_mxu_logic(ctx, tcg_gen_smax_i32);
+}
- if (unlikely(pad != 0)) {
- /* opcode padding incorrect -> do nothing */
- } else if (unlikely(XRa == 0)) {
- /* destination is zero register -> do nothing */
- } else if (unlikely((XRb == 0) && (XRc == 0))) {
- /* both operands zero registers -> just set destination to zero */
- tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
- } else if (unlikely((XRb == 0) || (XRc == 0))) {
- /* exactly one operand is zero register - find which one is not...*/
- uint32_t XRx = XRb ? XRb : XRc;
- /* ...and do max/min operation with one operand 0 */
- if (opc == OPC_MXU_S32MAX) {
- tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
- } else {
- tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
- }
- } else if (unlikely(XRb == XRc)) {
- /* both operands same -> just set destination to one of them */
- tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
- } else {
- /* the most general case */
- if (opc == OPC_MXU_S32MAX) {
- tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
- mxu_gpr[XRc - 1]);
- } else {
- tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
- mxu_gpr[XRc - 1]);
- }
- }
+static void gen_mxu_S32MIN(DisasContext *ctx)
+{
+ gen_mxu_logic(ctx, tcg_gen_smin_i32);
}
/*
@@ -4328,8 +4297,10 @@ static void decode_opc_mxu__pool00(DisasContext *ctx)
switch (opcode) {
case OPC_MXU_S32MAX:
+ gen_mxu_S32MAX(ctx);
+ break;
case OPC_MXU_S32MIN:
- gen_mxu_S32MAX_S32MIN(ctx);
+ gen_mxu_S32MIN(ctx);
break;
case OPC_MXU_D16MAX:
case OPC_MXU_D16MIN: