aboutsummaryrefslogtreecommitdiff
path: root/target/mips/tcg/mxu_translate.c
diff options
context:
space:
mode:
authorSiarhei Volkau <lis8215@gmail.com>2023-06-08 13:42:04 +0300
committerPhilippe Mathieu-Daudé <philmd@linaro.org>2023-07-10 23:33:38 +0200
commit9e51e0cd4bac9dd94f593d66497f635edd871d2e (patch)
treef62e26c5445381d5592ff82b09a792a6b91f95e8 /target/mips/tcg/mxu_translate.c
parenta9bfd80bd48f43ce333e8668f1b26b5cfd2d1ac2 (diff)
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>
Diffstat (limited to 'target/mips/tcg/mxu_translate.c')
-rw-r--r--target/mips/tcg/mxu_translate.c64
1 files changed, 64 insertions, 0 deletions
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;