@@ -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;