factor/vm/cpu-ppc.hpp

60 lines
1.5 KiB
C++
Executable File

namespace factor
{
#define FACTOR_CPU_STRING "ppc"
#define VM_ASM_API VM_C_API
register cell ds asm("r13");
register cell rs asm("r14");
inline static void check_call_site(cell return_address)
{
#ifdef FACTOR_DEBUG
cell insn = *(cell *)return_address;
assert((insn & 0x3) == 0x1);
assert((insn >> 26) == 0x12);
#endif
}
#define B_MASK 0x3fffffc
inline static void *get_call_target(cell return_address)
{
return_address -= sizeof(cell);
check_call_site(return_address);
cell insn = *(cell *)return_address;
cell unsigned_addr = (insn & B_MASK);
fixnum signed_addr = (fixnum)(unsigned_addr << 6) >> 6;
return (void *)(signed_addr + return_address);
}
inline static void set_call_target(cell return_address, void *target)
{
return_address -= sizeof(cell);
#ifdef FACTOR_DEBUG
assert((return_address & ~B_MASK) == 0);
check_call_site(return_address);
#endif
cell insn = *(cell *)return_address;
insn = ((insn & ~B_MASK) | (((cell)target - return_address) & B_MASK));
*(cell *)return_address = insn;
/* Flush the cache line containing the call we just patched */
__asm__ __volatile__ ("icbi 0, %0\n" "sync\n"::"r" (return_address):);
}
/* Defined in assembly */
VM_ASM_API void c_to_factor(cell quot);
VM_ASM_API void throw_impl(cell quot, stack_frame *rewind);
VM_ASM_API void lazy_jit_compile(cell quot);
VM_ASM_API void flush_icache(cell start, cell len);
VM_ASM_API void set_callstack(stack_frame *to,
stack_frame *from,
cell length,
void *(*memcpy)(void*,const void*, size_t));
}