+// read @Rn, @rm
+static void emit_indirect_read_double(u32 *rnr, u32 *rmr, int rn, int rm, int size)
+{
+ int tmp;
+
+ rcache_clean();
+ rcache_get_reg_arg(0, rn);
+ tmp = emit_memhandler_read(size);
+ emith_ctx_write(tmp, offsetof(SH2, drc_tmp));
+ rcache_free_tmp(tmp);
+ tmp = rcache_get_reg(rn, RC_GR_RMW);
+ emith_add_r_imm(tmp, 1 << size);
+
+ rcache_clean();
+ rcache_get_reg_arg(0, rm);
+ *rmr = emit_memhandler_read(size);
+ *rnr = rcache_get_tmp();
+ emith_ctx_read(*rnr, offsetof(SH2, drc_tmp));
+ tmp = rcache_get_reg(rm, RC_GR_RMW);
+ emith_add_r_imm(tmp, 1 << size);
+}
+
+// fixup for saturated MAC, to be called from generated code
+// FIXME: statically alloced regs need to be fixed
+static void sh2_macl_sat_fixup(void)
+{
+ if ((signed int)sh2->mach < 0 && sh2->mach < 0xffff8000)
+ {
+ sh2->mach = 0x00008000;
+ sh2->macl = 0x00000000;
+ }
+ else if ((signed int)sh2->mach > 0 && sh2->mach > 0x00007fff)
+ {
+ sh2->mach = 0x00007fff;
+ sh2->macl = 0xffffffff;
+ }
+}
+
+static void sh2_macw_sat_fixup(void)
+{
+ signed int t = sh2->mach;
+ if (t < -1 || (t == -1 && !(sh2->macl & 0x80000000)))
+ {
+ sh2->mach = 0xffffffff; // ?
+ sh2->macl = 0x80000000;
+ }
+ else if (t > 0 || (t == 0 && (sh2->macl & 0x80000000)))
+ {
+ sh2->mach = 0x7fffffff;
+ sh2->macl = 0xffffffff;
+ }
+}