target/mips/mxu: Fix D16MAX D16MIN Q8MAX Q8MIN instructions

These instructions were designed that they overwrite source
register during partial storing of result.

Signed-off-by: Siarhei Volkau <lis8215@gmail.com>
Message-Id: <20230608104222.1520143-7-lis8215@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
This commit is contained in:
Siarhei Volkau 2023-06-08 13:41:55 +03:00 committed by Philippe Mathieu-Daudé
parent 4051f035e0
commit fc34c76f36

View File

@ -1241,13 +1241,14 @@ static void gen_mxu_D16MAX_D16MIN(DisasContext *ctx)
/* ...and do half-word-wise max/min with one operand 0 */
TCGv_i32 t0 = tcg_temp_new();
TCGv_i32 t1 = tcg_constant_i32(0);
TCGv_i32 t2 = tcg_temp_new();
/* the left half-word first */
tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFFFF0000);
if (opc == OPC_MXU_D16MAX) {
tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
tcg_gen_smax_i32(t2, t0, t1);
} else {
tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
tcg_gen_smin_i32(t2, t0, t1);
}
/* the right half-word */
@ -1263,7 +1264,7 @@ static void gen_mxu_D16MAX_D16MIN(DisasContext *ctx)
/* return resulting half-words to its original position */
tcg_gen_shri_i32(t0, t0, 16);
/* finally update the destination */
tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
tcg_gen_or_i32(mxu_gpr[XRa - 1], t2, t0);
} 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]);
@ -1271,14 +1272,15 @@ static void gen_mxu_D16MAX_D16MIN(DisasContext *ctx)
/* the most general case */
TCGv_i32 t0 = tcg_temp_new();
TCGv_i32 t1 = tcg_temp_new();
TCGv_i32 t2 = tcg_temp_new();
/* the left half-word first */
tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFFFF0000);
tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
if (opc == OPC_MXU_D16MAX) {
tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
tcg_gen_smax_i32(t2, t0, t1);
} else {
tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
tcg_gen_smin_i32(t2, t0, t1);
}
/* the right half-word */
@ -1296,7 +1298,7 @@ static void gen_mxu_D16MAX_D16MIN(DisasContext *ctx)
/* return resulting half-words to its original position */
tcg_gen_shri_i32(t0, t0, 16);
/* finally update the destination */
tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
tcg_gen_or_i32(mxu_gpr[XRa - 1], t2, t0);
}
}
@ -1332,14 +1334,15 @@ static void gen_mxu_Q8MAX_Q8MIN(DisasContext *ctx)
/* ...and do byte-wise max/min with one operand 0 */
TCGv_i32 t0 = tcg_temp_new();
TCGv_i32 t1 = tcg_constant_i32(0);
TCGv_i32 t2 = tcg_temp_new();
int32_t i;
/* the leftmost byte (byte 3) first */
tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF000000);
if (opc == OPC_MXU_Q8MAX) {
tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
tcg_gen_smax_i32(t2, t0, t1);
} else {
tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
tcg_gen_smin_i32(t2, t0, t1);
}
/* bytes 2, 1, 0 */
@ -1357,8 +1360,9 @@ static void gen_mxu_Q8MAX_Q8MIN(DisasContext *ctx)
/* return resulting byte to its original position */
tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
/* finally update the destination */
tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
tcg_gen_or_i32(t2, t2, t0);
}
gen_store_mxu_gpr(t2, XRa);
} 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]);
@ -1366,15 +1370,16 @@ static void gen_mxu_Q8MAX_Q8MIN(DisasContext *ctx)
/* the most general case */
TCGv_i32 t0 = tcg_temp_new();
TCGv_i32 t1 = tcg_temp_new();
TCGv_i32 t2 = tcg_temp_new();
int32_t i;
/* the leftmost bytes (bytes 3) first */
tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF000000);
tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
if (opc == OPC_MXU_Q8MAX) {
tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
tcg_gen_smax_i32(t2, t0, t1);
} else {
tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
tcg_gen_smin_i32(t2, t0, t1);
}
/* bytes 2, 1, 0 */
@ -1394,8 +1399,9 @@ static void gen_mxu_Q8MAX_Q8MIN(DisasContext *ctx)
/* return resulting byte to its original position */
tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
/* finally update the destination */
tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
tcg_gen_or_i32(t2, t2, t0);
}
gen_store_mxu_gpr(t2, XRa);
}
}