// Move from Special Purpose Register static bool mfspr(PPCEmuAssembler& a, Instruction instr) { auto spr = decodeSPR(instr); auto dst = a.loadRegisterWrite(a.gpr[instr.rD]); switch (spr) { case SPR::XER: a.mov(dst, a.loadRegisterRead(a.xer)); break; case SPR::LR: a.mov(dst, a.lrMem); break; case SPR::CTR: a.mov(dst, a.ctrMem); break; case SPR::UGQR0: a.mov(dst, a.loadRegisterRead(a.gqr[0])); break; case SPR::UGQR1: a.mov(dst, a.loadRegisterRead(a.gqr[1])); break; case SPR::UGQR2: a.mov(dst, a.loadRegisterRead(a.gqr[2])); break; case SPR::UGQR3: a.mov(dst, a.loadRegisterRead(a.gqr[3])); break; case SPR::UGQR4: a.mov(dst, a.loadRegisterRead(a.gqr[4])); break; case SPR::UGQR5: a.mov(dst, a.loadRegisterRead(a.gqr[5])); break; case SPR::UGQR6: a.mov(dst, a.loadRegisterRead(a.gqr[6])); break; case SPR::UGQR7: a.mov(dst, a.loadRegisterRead(a.gqr[7])); break; case SPR::UPIR: a.mov(dst, a.coreIdMem); break; default: decaf_abort(fmt::format("Invalid mfspr SPR {}", static_cast<uint32_t>(spr))); } return true; }
// Move from Special Purpose Register static void mfspr(ThreadState *state, Instruction instr) { auto spr = decodeSPR(instr); auto value = 0u; switch (spr) { case SprEncoding::XER: value = state->xer.value; break; case SprEncoding::LR: value = state->lr; break; case SprEncoding::CTR: value = state->ctr; break; case SprEncoding::GQR0: value = state->gqr[0].value; break; case SprEncoding::GQR1: value = state->gqr[1].value; break; case SprEncoding::GQR2: value = state->gqr[2].value; break; case SprEncoding::GQR3: value = state->gqr[3].value; break; case SprEncoding::GQR4: value = state->gqr[4].value; break; case SprEncoding::GQR5: value = state->gqr[5].value; break; case SprEncoding::GQR6: value = state->gqr[6].value; break; case SprEncoding::GQR7: value = state->gqr[7].value; break; default: gLog->error("Invalid mfspr SPR {}", static_cast<uint32_t>(spr)); } state->gpr[instr.rD] = value; }
// Move from Time Base Register static void mftb(ThreadState *state, Instruction instr) { auto tbr = decodeSPR(instr); auto value = 0u; switch (tbr) { case SprEncoding::TBL: value = state->tbl; break; case SprEncoding::TBU: value = state->tbu; break; default: gLog->error("Invalid mftb TBR {}", static_cast<uint32_t>(tbr)); } state->gpr[instr.rD] = value; }