// Kernel call static bool kc(PPCEmuAssembler& a, Instruction instr) { auto id = instr.kcn; auto kc = cpu::getKernelCall(id); decaf_assert(kc, fmt::format("Encountered invalid Kernel Call ID {}", id)); // Evict all stored register as a KC might read or modify them. a.evictAll(); // Save NIA back to memory in case KC reads/writes it a.mov(a.niaMem, a.genCia + 4); // Call the KC a.mov(a.sysArgReg[0], asmjit::Ptr(kc->func)); a.mov(a.sysArgReg[1], asmjit::Ptr(kc->user_data)); a.call(asmjit::Ptr(&kc_stub)); a.mov(a.stateReg, asmjit::x86::rax); // Check if the KC adjusted nia. If it has, we need to return // to the dispatcher. Note that we assume the cache was already // cleared before this instruction since KC requires that anyways. auto niaUnchangedLbl = a.newLabel(); a.cmp(a.niaMem, a.genCia + 4); a.je(niaUnchangedLbl); a.mov(a.finaleNiaArgReg, a.niaMem); a.mov(a.finaleJmpSrcArgReg, 0); a.jmp(asmjit::Ptr(gFinaleFn)); a.bind(niaUnchangedLbl); return true; }
bool jit_fallback(PPCEmuAssembler& a, Instruction instr) { auto data = gInstructionTable.decode(instr); auto fptr = sInstructionMap[static_cast<size_t>(data->id)]; if (!fptr) { assert(0); } //printf("JIT Fallback for `%s`\n", data->name); a.mov(a.zcx, a.state); a.mov(a.edx, (uint32_t)instr); a.call(asmjit::Ptr(fptr)); return true; }
bool jit_fallback(PPCEmuAssembler& a, Instruction instr) { auto data = gInstructionTable.decode(instr); auto fptr = cpu::interpreter::getInstructionHandler(data->id); if (!fptr) { throw; } if (TRACK_FALLBACK_CALLS) { a.mov(a.zax, reinterpret_cast<intptr_t>(&sFallbackCalls[static_cast<uint32_t>(data->id)])); a.lock(); a.inc(asmjit::X86Mem(a.zax, 0)); } a.mov(a.zcx, a.state); a.mov(a.edx, (uint32_t)instr); a.call(asmjit::Ptr(fptr)); return true; }
bool jit_fallback(PPCEmuAssembler& a, espresso::Instruction instr) { auto data = espresso::decodeInstruction(instr); decaf_assert(data, fmt::format("Failed to decode instruction {:08X}", instr.value)); auto fptr = cpu::interpreter::getInstructionHandler(data->id); decaf_assert(fptr, fmt::format("Unimplemented instruction {}", static_cast<int>(data->id))); a.evictAll(); if (TRACK_FALLBACK_CALLS) { auto fallbackAddr = reinterpret_cast<intptr_t>(&sFallbackCalls[static_cast<uint32_t>(data->id)]); a.mov(asmjit::x86::rax, asmjit::Ptr(fallbackAddr)); a.lock().inc(asmjit::X86Mem(asmjit::x86::rax, 0)); } a.mov(a.sysArgReg[0], a.stateReg); a.mov(a.sysArgReg[1], (uint32_t)instr); a.call(asmjit::Ptr(fptr)); return true; }