gen_store_gpr(tmp, a->rd);
return true;
}
+
+static bool trans_QMAC(DisasContext *ctx, arg_QMAC *a)
+{
+ TCGv_i64 t0 = tcg_temp_new_i64();
+ TCGv_i64 t1 = tcg_temp_new_i64();
+
+ gen_load_gpr(t0, a->rt);
+ gen_load_gpr(t1, a->rs);
+
+ /* t0 = rt<0> * rs<lane> * 2 */
+ tcg_gen_ext16s_i64(t0, t0);
+ tcg_gen_sextract_i64(t1, t1, a->lane * 16, 16);
+ tcg_gen_mul_i64(t0, t0, t1);
+ tcg_gen_add_i64(t0, t0, t0);
+
+ /* Saturate -0x8000 * -0x8000 * 2 = 0x80000000 -> 0x7fffffff */
+ tcg_gen_smin_i64(t0, t0, tcg_constant_i64(INT32_MAX));
+
+ /* HI:LO += t0 */
+ tcg_gen_concat32_i64(t1, cpu_LO[0], cpu_HI[0]);
+ tcg_gen_add_i64(t0, t0, t1);
+ tcg_gen_sextract_i64(cpu_LO[0], t0, 0, 32);
+ tcg_gen_sextract_i64(cpu_HI[0], t0, 32, 32);
+ return true;
+}
+
+static bool trans_QMACS(DisasContext *ctx, arg_QMACS *a)
+{
+ TCGv_i64 min32 = tcg_constant_i64(INT32_MIN);
+ TCGv_i64 max32 = tcg_constant_i64(INT32_MAX);
+ TCGv_i64 t0 = tcg_temp_new_i64();
+ TCGv_i64 t1 = tcg_temp_new_i64();
+
+ gen_load_gpr(t0, a->rt);
+ gen_load_gpr(t1, a->rs);
+
+ /* t0 = rt<0> * rs<lane> * 2 */
+ tcg_gen_ext16s_i64(t0, t0);
+ tcg_gen_sextract_i64(t1, t1, a->lane * 16, 16);
+ tcg_gen_mul_i64(t0, t0, t1);
+ tcg_gen_add_i64(t0, t0, t0);
+
+ /*
+ * Saturate -0x8000 * -0x8000 * 2 = 0x80000000 -> 0x7fffffff.
+ * Accumulate overflow in HI[0].
+ */
+ tcg_gen_smin_i64(t1, t0, max32);
+ tcg_gen_setcond_i64(TCG_COND_NE, t0, t0, t1);
+ tcg_gen_or_i64(cpu_HI[0], cpu_HI[0], t0);
+
+ /*
+ * LO = sat32(LO + t0)
+ * Accumulate overflow in HI[0].
+ */
+ tcg_gen_ext32s_i64(t0, cpu_LO[0]);
+ tcg_gen_add_i64(t0, t0, t1);
+ tcg_gen_smin_i64(cpu_LO[0], t0, max32);
+ tcg_gen_smax_i64(cpu_LO[0], cpu_LO[0], min32);
+ tcg_gen_setcond_i64(TCG_COND_NE, t0, t0, cpu_LO[0]);
+ tcg_gen_or_i64(cpu_HI[0], cpu_HI[0], t0);
+ return true;
+}