+static void doBranchReg(u32 tar) {
+#ifdef DO_EXCEPTION_ADDR_ERR
+ if (unlikely(tar & 3)) {
+ psxRegs.pc = psxRegs.CP0.n.BadVAddr = tar;
+ psxException(R3000E_AdEL << 2, branch, &psxRegs.CP0);
+ return;
+ }
+#else
+ tar &= ~3;
+#endif
+ doBranch(tar);
+}
+
+#if __has_builtin(__builtin_add_overflow) || (defined(__GNUC__) && __GNUC__ >= 5)
+#define add_overflow(a, b, r) __builtin_add_overflow(a, b, &(r))
+#define sub_overflow(a, b, r) __builtin_sub_overflow(a, b, &(r))
+#else
+#define add_overflow(a, b, r) ({r = (u32)a + (u32)b; (a ^ ~b) & (a ^ r) & (1u<<31);})
+#define sub_overflow(a, b, r) ({r = (u32)a - (u32)b; (a ^ b) & (a ^ r) & (1u<<31);})
+#endif
+
+static void addExc(psxRegisters *regs, u32 rt, s32 a1, s32 a2) {
+ s32 r;
+ if (add_overflow(a1, a2, r)) {
+ //printf("ov %08x + %08x = %08x\n", a1, a2, r);
+ regs->pc -= 4;
+ psxException(R3000E_Ov << 2, branch, ®s->CP0);
+ return;
+ }
+ if (rt)
+ regs->GPR.r[rt] = r;
+}
+
+static void subExc(psxRegisters *regs, u32 rt, s32 a1, s32 a2) {
+ s32 r;
+ if (sub_overflow(a1, a2, r)) {
+ regs->pc -= 4;
+ psxException(R3000E_Ov << 2, branch, ®s->CP0);
+ return;
+ }
+ if (rt)
+ regs->GPR.r[rt] = r;
+}
+