Example #1
0
// 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;
}
Example #2
0
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;
}
Example #3
0
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;
}
Example #4
0
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;
}