From: Siarhei Volkau Date: Thu, 8 Jun 2023 10:42:04 +0000 (+0300) Subject: target/mips/mxu: Add D32ADD instruction X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=9e51e0cd4bac9dd94f593d66497f635edd871d2e;p=qmiga%2Fqemu.git 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 Message-Id: <20230608104222.1520143-16-lis8215@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- diff --git a/target/mips/tcg/mxu_translate.c b/target/mips/tcg/mxu_translate.c index dc4fdf1dd9..b133f9f11d 100644 --- a/target/mips/tcg/mxu_translate.c +++ b/target/mips/tcg/mxu_translate.c @@ -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, @@ -2248,6 +2249,66 @@ static void gen_mxu_q16add(DisasContext *ctx) } /* + * 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;