- else if (op.r.rs == OP_CP2_BASIC_MFC2)
- return lightrec_mfc2(state, op.r.rd);
- else
- return state->regs.cp2c[op.r.rd];
+
+ if (op.i.op == OP_SWC2) {
+ val = lightrec_mfc2(state, op.i.rt);
+ } else if (op.r.rs == OP_CP2_BASIC_MFC2)
+ val = lightrec_mfc2(state, op.r.rd);
+ else {
+ val = state->regs.cp2c[op.r.rd];
+
+ switch (op.r.rd) {
+ case 4:
+ case 12:
+ case 20:
+ case 26:
+ case 27:
+ case 29:
+ case 30:
+ val = (u32)(s16)val;
+ fallthrough;
+ default:
+ break;
+ }
+ }
+
+ if (state->ops.cop2_notify)
+ (*state->ops.cop2_notify)(state, op.opcode, val);
+
+ return val;
+}
+
+static void lightrec_mfc_cb(struct lightrec_state *state, union code op)
+{
+ u32 rt = lightrec_mfc(state, op);
+
+ if (op.i.op == OP_SWC2)
+ state->cp2_temp_reg = rt;
+ else if (op.r.rt)
+ state->regs.gpr[op.r.rt] = rt;