From 3569e97e0efaba850097490b03850f0f0261413e Mon Sep 17 00:00:00 2001 From: beeanyew Date: Sun, 28 Aug 2022 20:02:39 +0200 Subject: [PATCH] [CPU] Add rldicx implementation NOTE: May or may not be correct, but works for 535507D4. --- src/xenia/cpu/ppc/ppc_emit_alu.cc | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/xenia/cpu/ppc/ppc_emit_alu.cc b/src/xenia/cpu/ppc/ppc_emit_alu.cc index 348e050c5..9e030a460 100644 --- a/src/xenia/cpu/ppc/ppc_emit_alu.cc +++ b/src/xenia/cpu/ppc/ppc_emit_alu.cc @@ -913,8 +913,26 @@ int InstrEmit_rldcrx(PPCHIRBuilder& f, const InstrData& i) { } int InstrEmit_rldicx(PPCHIRBuilder& f, const InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + // n <- sh[5] || sh[0:4] + // r <- ROTL64(RS, n) + // b <- mb[5] || mb[0:4] + // m <- MASK(b, ~n) + // RA <- r & m + // TODO: Check if this makes any sense. It works in 535507D4, + // but it's the only title I could find that uses this instruction. + uint32_t sh = (i.MD.SH5 << 5) | i.MD.SH; + uint32_t mb = (i.MD.MB5 << 5) | i.MD.MB; + uint64_t m = XEMASK(mb, ~sh); + Value* v = f.LoadGPR(i.MD.RT); + if (sh) { + v = f.RotateLeft(v, f.LoadConstantInt8(sh)); + } + v = f.And(v, f.LoadConstantUint64(m)); + f.StoreGPR(i.MD.RA, v); + if (i.MD.Rc) { + f.UpdateCR(0, v); + } + return 0; } int InstrEmit_rldiclx(PPCHIRBuilder& f, const InstrData& i) {