block_of_code: Make CallFunction accept function pointers only

This commit is contained in:
Lioncash 2016-08-31 16:09:26 -04:00 committed by MerryMage
parent 249a2be786
commit ea6a4e82b5
3 changed files with 36 additions and 32 deletions

View file

@ -128,17 +128,6 @@ void BlockOfCode::SwitchMxcsrOnExit() {
ldmxcsr(dword[r15 + offsetof(JitState, save_host_MXCSR)]);
}
void BlockOfCode::CallFunction(const void* fn) {
u64 distance = u64(fn) - (getCurr<u64>() + 5);
if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) {
// Far call
mov(rax, u64(fn));
call(rax);
} else {
call(fn);
}
}
void BlockOfCode::nop(size_t size) {
switch (size) {
case 0:

View file

@ -6,9 +6,7 @@
#pragma once
#include <array>
#include <vector>
#include <type_traits>
#include <xbyak.h>
#include "backend_x64/jitstate.h"
@ -32,8 +30,24 @@ public:
void SwitchMxcsrOnEntry();
/// Code emitter: Makes saved host MXCSR the current MXCSR
void SwitchMxcsrOnExit();
/// Code emitter: Calls the function
void CallFunction(const void* fn);
template <typename FunctionPointer>
void CallFunction(FunctionPointer fn) {
static_assert(std::is_pointer<FunctionPointer>() && std::is_function<std::remove_pointer_t<FunctionPointer>>(),
"Supplied type must be a pointer to a function");
const u64 address = reinterpret_cast<u64>(fn);
const u64 distance = address - (getCurr<u64>() + 5);
if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) {
// Far call
mov(rax, address);
call(rax);
} else {
call(fn);
}
}
Xbyak::Address MFloatPositiveZero32() {
return xword[rip + consts.FloatPositiveZero32];

View file

@ -324,7 +324,7 @@ void EmitX64::EmitCallSupervisor(IR::Block&, IR::Inst* inst) {
reg_alloc.HostCall(nullptr, imm32);
code->SwitchMxcsrOnExit();
code->CallFunction(reinterpret_cast<void*>(cb.CallSVC));
code->CallFunction(cb.CallSVC);
code->SwitchMxcsrOnEntry();
}
@ -337,7 +337,7 @@ void EmitX64::EmitGetFpscr(IR::Block&, IR::Inst* inst) {
code->mov(code->ABI_PARAM1, code->r15);
code->SwitchMxcsrOnExit();
code->CallFunction(reinterpret_cast<void*>(&GetFpscrImpl));
code->CallFunction(&GetFpscrImpl);
code->SwitchMxcsrOnEntry();
}
@ -352,7 +352,7 @@ void EmitX64::EmitSetFpscr(IR::Block&, IR::Inst* inst) {
code->mov(code->ABI_PARAM2, code->r15);
code->SwitchMxcsrOnExit();
code->CallFunction(reinterpret_cast<void*>(&SetFpscrImpl));
code->CallFunction(&SetFpscrImpl);
code->SwitchMxcsrOnEntry();
}
@ -1832,52 +1832,53 @@ void EmitX64::EmitSetExclusive(IR::Block&, IR::Inst* inst) {
void EmitX64::EmitReadMemory8(IR::Block&, IR::Inst* inst) {
reg_alloc.HostCall(inst, inst->GetArg(0));
code->CallFunction(reinterpret_cast<void*>(cb.MemoryRead8));
code->CallFunction(cb.MemoryRead8);
}
void EmitX64::EmitReadMemory16(IR::Block&, IR::Inst* inst) {
reg_alloc.HostCall(inst, inst->GetArg(0));
code->CallFunction(reinterpret_cast<void*>(cb.MemoryRead16));
code->CallFunction(cb.MemoryRead16);
}
void EmitX64::EmitReadMemory32(IR::Block&, IR::Inst* inst) {
reg_alloc.HostCall(inst, inst->GetArg(0));
code->CallFunction(reinterpret_cast<void*>(cb.MemoryRead32));
code->CallFunction(cb.MemoryRead32);
}
void EmitX64::EmitReadMemory64(IR::Block&, IR::Inst* inst) {
reg_alloc.HostCall(inst, inst->GetArg(0));
code->CallFunction(reinterpret_cast<void*>(cb.MemoryRead64));
code->CallFunction(cb.MemoryRead64);
}
void EmitX64::EmitWriteMemory8(IR::Block&, IR::Inst* inst) {
reg_alloc.HostCall(nullptr, inst->GetArg(0), inst->GetArg(1));
code->CallFunction(reinterpret_cast<void*>(cb.MemoryWrite8));
code->CallFunction(cb.MemoryWrite8);
}
void EmitX64::EmitWriteMemory16(IR::Block&, IR::Inst* inst) {
reg_alloc.HostCall(nullptr, inst->GetArg(0), inst->GetArg(1));
code->CallFunction(reinterpret_cast<void*>(cb.MemoryWrite16));
code->CallFunction(cb.MemoryWrite16);
}
void EmitX64::EmitWriteMemory32(IR::Block&, IR::Inst* inst) {
reg_alloc.HostCall(nullptr, inst->GetArg(0), inst->GetArg(1));
code->CallFunction(reinterpret_cast<void*>(cb.MemoryWrite32));
code->CallFunction(cb.MemoryWrite32);
}
void EmitX64::EmitWriteMemory64(IR::Block&, IR::Inst* inst) {
reg_alloc.HostCall(nullptr, inst->GetArg(0), inst->GetArg(1));
code->CallFunction(reinterpret_cast<void*>(cb.MemoryWrite64));
code->CallFunction(cb.MemoryWrite64);
}
static void ExclusiveWrite(BlockOfCode* code, RegAlloc& reg_alloc, IR::Inst* inst, void* fn) {
template <typename FunctionPointer>
static void ExclusiveWrite(BlockOfCode* code, RegAlloc& reg_alloc, IR::Inst* inst, FunctionPointer fn) {
using namespace Xbyak::util;
Xbyak::Label end;
@ -1899,15 +1900,15 @@ static void ExclusiveWrite(BlockOfCode* code, RegAlloc& reg_alloc, IR::Inst* ins
}
void EmitX64::EmitExclusiveWriteMemory8(IR::Block&, IR::Inst* inst) {
ExclusiveWrite(code, reg_alloc, inst, reinterpret_cast<void*>(cb.MemoryWrite8));
ExclusiveWrite(code, reg_alloc, inst, cb.MemoryWrite8);
}
void EmitX64::EmitExclusiveWriteMemory16(IR::Block&, IR::Inst* inst) {
ExclusiveWrite(code, reg_alloc, inst, reinterpret_cast<void*>(cb.MemoryWrite16));
ExclusiveWrite(code, reg_alloc, inst, cb.MemoryWrite16);
}
void EmitX64::EmitExclusiveWriteMemory32(IR::Block&, IR::Inst* inst) {
ExclusiveWrite(code, reg_alloc, inst, reinterpret_cast<void*>(cb.MemoryWrite32));
ExclusiveWrite(code, reg_alloc, inst, cb.MemoryWrite32);
}
void EmitX64::EmitExclusiveWriteMemory64(IR::Block&, IR::Inst* inst) {
@ -1931,7 +1932,7 @@ void EmitX64::EmitExclusiveWriteMemory64(IR::Block&, IR::Inst* inst) {
code->mov(value.cvt32(), value.cvt32()); // zero extend to 64-bits
code->shl(value_hi, 32);
code->or_(value, value_hi);
code->CallFunction(reinterpret_cast<void*>(cb.MemoryWrite64));
code->CallFunction(cb.MemoryWrite64);
code->xor_(passed, passed);
code->L(end);
}
@ -2107,7 +2108,7 @@ void EmitX64::EmitTerminalInterpret(IR::Term::Interpret terminal, Arm::LocationD
code->mov(code->ABI_PARAM2, reinterpret_cast<u64>(jit_interface));
code->mov(MJitStateReg(Arm::Reg::PC), code->ABI_PARAM1.cvt32());
code->SwitchMxcsrOnExit();
code->CallFunction(reinterpret_cast<void*>(cb.InterpreterFallback));
code->CallFunction(cb.InterpreterFallback);
code->ReturnFromRunCode(false); // TODO: Check cycles
}