target/mips/mxu: Add D32ADD instruction

The instruction adds/subtracts two 32-bit values in XRb and XRc.
Placing results in XRa and XRd and updates carry bits for each
path in the MXU control register.

Signed-off-by: Siarhei Volkau <lis8215@gmail.com>
Message-Id: <20230608104222.1520143-16-lis8215@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
This commit is contained in:
Siarhei Volkau 2023-06-08 13:42:04 +03:00 committed by Philippe Mathieu-Daudé
parent a9bfd80bd4
commit 9e51e0cd4b

View File

@ -376,6 +376,7 @@ enum {
OPC_MXU__POOL09 = 0x15,
OPC_MXU__POOL10 = 0x16,
OPC_MXU__POOL11 = 0x17,
OPC_MXU_D32ADD = 0x18,
OPC_MXU_S8LDD = 0x22,
OPC_MXU__POOL16 = 0x27,
OPC_MXU__POOL17 = 0x28,
@ -2247,6 +2248,66 @@ static void gen_mxu_q16add(DisasContext *ctx)
tcg_gen_or_tl(mxu_gpr[XRd - 1], t0, t1);
}
/*
* D32ADD XRa, XRb, XRc, XRd, aptn2 - Double
* 32 bit pattern addition/subtraction.
*/
static void gen_mxu_d32add(DisasContext *ctx)
{
uint32_t aptn2, pad, XRc, XRb, XRa, XRd;
aptn2 = extract32(ctx->opcode, 24, 2);
pad = extract32(ctx->opcode, 22, 2);
XRd = extract32(ctx->opcode, 18, 4);
XRc = extract32(ctx->opcode, 14, 4);
XRb = extract32(ctx->opcode, 10, 4);
XRa = extract32(ctx->opcode, 6, 4);
TCGv t0 = tcg_temp_new();
TCGv t1 = tcg_temp_new();
TCGv t2 = tcg_temp_new();
TCGv carry = tcg_temp_new();
TCGv cr = tcg_temp_new();
if (unlikely(pad != 0)) {
/* opcode padding incorrect -> do nothing */
} else if (unlikely(XRa == 0 && XRd == 0)) {
/* destinations are zero register -> do nothing */
} else {
/* common case */
gen_load_mxu_gpr(t0, XRb);
gen_load_mxu_gpr(t1, XRc);
gen_load_mxu_cr(cr);
if (XRa != 0) {
if (aptn2 & 2) {
tcg_gen_sub_i32(t2, t0, t1);
tcg_gen_setcond_tl(TCG_COND_GTU, carry, t0, t1);
} else {
tcg_gen_add_i32(t2, t0, t1);
tcg_gen_setcond_tl(TCG_COND_GTU, carry, t0, t2);
}
tcg_gen_andi_tl(cr, cr, 0x7fffffff);
tcg_gen_shli_tl(carry, carry, 31);
tcg_gen_or_tl(cr, cr, carry);
gen_store_mxu_gpr(t2, XRa);
}
if (XRd != 0) {
if (aptn2 & 1) {
tcg_gen_sub_i32(t2, t0, t1);
tcg_gen_setcond_tl(TCG_COND_GTU, carry, t0, t1);
} else {
tcg_gen_add_i32(t2, t0, t1);
tcg_gen_setcond_tl(TCG_COND_GTU, carry, t0, t2);
}
tcg_gen_andi_tl(cr, cr, 0xbfffffff);
tcg_gen_shli_tl(carry, carry, 30);
tcg_gen_or_tl(cr, cr, carry);
gen_store_mxu_gpr(t2, XRd);
}
gen_store_mxu_cr(cr);
}
}
/*
* MXU instruction category: Miscellaneous
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -3031,6 +3092,9 @@ bool decode_ase_mxu(DisasContext *ctx, uint32_t insn)
case OPC_MXU__POOL11:
decode_opc_mxu__pool11(ctx);
break;
case OPC_MXU_D32ADD:
gen_mxu_d32add(ctx);
break;
case OPC_MXU_S8LDD:
gen_mxu_s8ldd(ctx);
break;