From fb76cbb29119b8c6d78153b09bbe7e02e206713c Mon Sep 17 00:00:00 2001 From: "Herman S." <429230+has207@users.noreply.github.com> Date: Sun, 19 Oct 2025 14:03:55 +0900 Subject: [PATCH] [CPU/PPC] Implement mcrxr instruction Implement mcrxr (Move to Condition Register from XER). Copies XER condition bits (SO, OV, CA) to a CR field and clears those bits in XER. This was previously unimplemented. --- src/xenia/cpu/ppc/ppc_emit_control.cc | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/xenia/cpu/ppc/ppc_emit_control.cc b/src/xenia/cpu/ppc/ppc_emit_control.cc index ff2dcc0e8..0b81b79b7 100644 --- a/src/xenia/cpu/ppc/ppc_emit_control.cc +++ b/src/xenia/cpu/ppc/ppc_emit_control.cc @@ -430,6 +430,26 @@ int InstrEmit_mcrf(PPCHIRBuilder& f, const InstrData& i) { return 0; } +int InstrEmit_mcrxr(PPCHIRBuilder& f, const InstrData& i) { + // CR[4*CRFD:4*CRFD+3] <- XER[0:3] + // XER[0:3] <- 0 + // XER bits: SO (bit 31), OV (bit 30), CA (bit 29), reserved (bit 28) + + uint32_t crfd = i.X.RT >> 2; + Value* xer = f.LoadXER(); + + // Extract XER[0:3] which are bits 31-28 + Value* xer_bits = f.And(f.Shr(xer, 28), f.LoadConstantUint64(0xF)); + + // Store to CR field + f.StoreCR(crfd, f.Shl(xer_bits, 4 * (7 - crfd))); + + // Clear XER[0:3] (bits 31-28) + f.StoreXER(f.And(xer, f.LoadConstantUint64(~(0xFULL << 28)))); + + return 0; +} + // System linkage (A-24) int InstrEmit_sc(PPCHIRBuilder& f, const InstrData& i) { @@ -831,6 +851,7 @@ void RegisterEmitCategoryControl() { XEREGISTERINSTR(crorc); XEREGISTERINSTR(crxor); XEREGISTERINSTR(mcrf); + XEREGISTERINSTR(mcrxr); XEREGISTERINSTR(sc); XEREGISTERINSTR(td); XEREGISTERINSTR(tdi);