-namespace factor
-{
+namespace factor {
#define FACTOR_CPU_STRING "arm"
-#define FRAME_RETURN_ADDRESS(frame,vm) *(XT *)(vm->frame_successor(frame) + 1)
+#define FRAME_RETURN_ADDRESS(frame, vm) *(XT*)(vm->frame_successor(frame) + 1)
}
-namespace factor
-{
+namespace factor {
#ifdef FACTOR_64
#define FACTOR_CPU_STRING "ppc.64"
#define FACTOR_CPU_STRING "ppc.32"
#endif
-#define CALLSTACK_BOTTOM(ctx) (void *)(ctx->callstack_seg->end - 32)
+#define CALLSTACK_BOTTOM(ctx) (void*)(ctx->callstack_seg->end - 32)
/* In the instruction sequence:
the branch is one instruction. */
static const fixnum xt_tail_pic_offset = 4;
-inline static void check_call_site(cell return_address)
-{
- u32 insn = *(u32 *)return_address;
- /* Check that absolute bit is 0 */
- FACTOR_ASSERT((insn & 0x2) == 0x0);
- /* Check that instruction is branch */
- FACTOR_ASSERT((insn >> 26) == 0x12);
+inline static void check_call_site(cell return_address) {
+ u32 insn = *(u32*)return_address;
+ /* Check that absolute bit is 0 */
+ FACTOR_ASSERT((insn & 0x2) == 0x0);
+ /* Check that instruction is branch */
+ FACTOR_ASSERT((insn >> 26) == 0x12);
}
static const u32 b_mask = 0x3fffffc;
-inline static void *get_call_target(cell return_address)
-{
- return_address -= 4;
- check_call_site(return_address);
+inline static void* get_call_target(cell return_address) {
+ return_address -= 4;
+ check_call_site(return_address);
- u32 insn = *(u32 *)return_address;
- u32 unsigned_addr = (insn & b_mask);
- s32 signed_addr = (s32)(unsigned_addr << 6) >> 6;
- return (void *)(signed_addr + return_address);
+ u32 insn = *(u32*)return_address;
+ u32 unsigned_addr = (insn & b_mask);
+ s32 signed_addr = (s32)(unsigned_addr << 6) >> 6;
+ return (void*)(signed_addr + return_address);
}
-inline static void set_call_target(cell return_address, void *target)
-{
- return_address -= 4;
- check_call_site(return_address);
+inline static void set_call_target(cell return_address, void* target) {
+ return_address -= 4;
+ check_call_site(return_address);
- u32 insn = *(u32 *)return_address;
+ u32 insn = *(u32*)return_address;
- fixnum relative_address = ((cell)target - return_address);
- insn = ((insn & ~b_mask) | (relative_address & b_mask));
- *(u32 *)return_address = insn;
+ fixnum relative_address = ((cell) target - return_address);
+ insn = ((insn & ~b_mask) | (relative_address & b_mask));
+ *(u32*)return_address = insn;
- /* Flush the cache line containing the call we just patched */
- __asm__ __volatile__ ("icbi 0, %0\n" "sync\n"::"r" (return_address):);
+ /* Flush the cache line containing the call we just patched */
+ __asm__ __volatile__("icbi 0, %0\n"
+ "sync\n" ::"r"(return_address)
+ :);
}
-inline static bool tail_call_site_p(cell return_address)
-{
- return_address -= 4;
- u32 insn = *(u32 *)return_address;
- return (insn & 0x1) == 0;
+inline static bool tail_call_site_p(cell return_address) {
+ return_address -= 4;
+ u32 insn = *(u32*)return_address;
+ return (insn & 0x1) == 0;
}
-inline static unsigned int fpu_status(unsigned int status)
-{
- unsigned int r = 0;
-
- if (status & 0x20000000)
- r |= FP_TRAP_INVALID_OPERATION;
- if (status & 0x10000000)
- r |= FP_TRAP_OVERFLOW;
- if (status & 0x08000000)
- r |= FP_TRAP_UNDERFLOW;
- if (status & 0x04000000)
- r |= FP_TRAP_ZERO_DIVIDE;
- if (status & 0x02000000)
- r |= FP_TRAP_INEXACT;
-
- return r;
+inline static unsigned int fpu_status(unsigned int status) {
+ unsigned int r = 0;
+
+ if (status & 0x20000000)
+ r |= FP_TRAP_INVALID_OPERATION;
+ if (status & 0x10000000)
+ r |= FP_TRAP_OVERFLOW;
+ if (status & 0x08000000)
+ r |= FP_TRAP_UNDERFLOW;
+ if (status & 0x04000000)
+ r |= FP_TRAP_ZERO_DIVIDE;
+ if (status & 0x02000000)
+ r |= FP_TRAP_INEXACT;
+
+ return r;
}
/* Defined in assembly */
-namespace factor
-{
+namespace factor {
#define FACTOR_CPU_STRING "x86.32"
-namespace factor
-{
+namespace factor {
#define FACTOR_CPU_STRING "x86.64"
#include "master.hpp"
-namespace factor
-{
-
-void factor_vm::dispatch_signal_handler(cell *sp, cell *pc, cell handler)
-{
- if (!code->seg->in_segment_p(*pc) || *sp < ctx->callstack_seg->start + stack_reserved)
- {
- /* Fault came from foreign code or a callstack overflow, or we don't
- have enough callstack room to try the resumable handler. Cut the
- callstack down to the shallowest Factor stack frame that leaves room for
- the signal handler to do its thing, and launch the handler without going
- through the resumable subprimitive. */
- signal_resumable = false;
- void *frame_top = (void*)ctx->callstack_top;
-
- while(frame_top < ctx->callstack_bottom
- && (cell)frame_top < ctx->callstack_seg->start + stack_reserved)
- {
- frame_top = frame_predecessor(frame_top);
- }
-
- *sp = (cell)frame_top;
- ctx->callstack_top = frame_top;
- *pc = handler;
- } else {
- signal_resumable = true;
- // Fault came from Factor, and we've got a good callstack. Route the signal
- // handler through the resumable signal handler subprimitive.
- cell offset = *sp % 16;
-
- signal_handler_addr = handler;
- tagged<word> handler_word = tagged<word>(special_objects[SIGNAL_HANDLER_WORD]);
-
- /* True stack frames are always 16-byte aligned. Leaf procedures
- that don't create a stack frame will be out of alignment by sizeof(cell)
- bytes. */
- /* On architectures with a link register we would have to check for leafness
- by matching the PC to a word. We should also use FRAME_RETURN_ADDRESS instead
- of assuming the stack pointer is the right place to put the resume address. */
- if (offset == 0)
- {
- cell newsp = *sp - sizeof(cell);
- *sp = newsp;
- *(cell*)newsp = *pc;
- }
- else if (offset == 16 - sizeof(cell))
- {
- // Make a fake frame for the leaf procedure
- FACTOR_ASSERT(code->code_block_for_address(*pc) != NULL);
-
- cell newsp = *sp - LEAF_FRAME_SIZE;
- *(cell*)newsp = *pc;
- *sp = newsp;
- handler_word = tagged<word>(special_objects[LEAF_SIGNAL_HANDLER_WORD]);
- }
- else
- FACTOR_ASSERT(false);
-
- *pc = (cell)handler_word->entry_point;
- }
+namespace factor {
+
+void factor_vm::dispatch_signal_handler(cell* sp, cell* pc, cell handler) {
+ if (!code->seg->in_segment_p(*pc) ||
+ *sp < ctx->callstack_seg->start + stack_reserved) {
+ /* Fault came from foreign code or a callstack overflow, or we don't
+ have enough callstack room to try the resumable handler. Cut the
+ callstack down to the shallowest Factor stack frame that leaves room for
+ the signal handler to do its thing, and launch the handler without going
+ through the resumable subprimitive. */
+ signal_resumable = false;
+ void* frame_top = (void*)ctx->callstack_top;
+
+ while (frame_top < ctx->callstack_bottom &&
+ (cell) frame_top < ctx->callstack_seg->start + stack_reserved) {
+ frame_top = frame_predecessor(frame_top);
+ }
+
+ *sp = (cell) frame_top;
+ ctx->callstack_top = frame_top;
+ *pc = handler;
+ } else {
+ signal_resumable = true;
+ // Fault came from Factor, and we've got a good callstack. Route the signal
+ // handler through the resumable signal handler subprimitive.
+ cell offset = *sp % 16;
+
+ signal_handler_addr = handler;
+ tagged<word> handler_word =
+ tagged<word>(special_objects[SIGNAL_HANDLER_WORD]);
+
+ /* True stack frames are always 16-byte aligned. Leaf procedures
+ that don't create a stack frame will be out of alignment by sizeof(cell)
+ bytes. */
+ /* On architectures with a link register we would have to check for leafness
+ by matching the PC to a word. We should also use FRAME_RETURN_ADDRESS
+ instead of assuming the stack pointer is the right place to put the
+ resume address. */
+ if (offset == 0) {
+ cell newsp = *sp - sizeof(cell);
+ *sp = newsp;
+ *(cell*)newsp = *pc;
+ } else if (offset == 16 - sizeof(cell)) {
+ // Make a fake frame for the leaf procedure
+ FACTOR_ASSERT(code->code_block_for_address(*pc) != NULL);
+
+ cell newsp = *sp - LEAF_FRAME_SIZE;
+ *(cell*)newsp = *pc;
+ *sp = newsp;
+ handler_word = tagged<word>(special_objects[LEAF_SIGNAL_HANDLER_WORD]);
+ } else
+ FACTOR_ASSERT(false);
+
+ *pc = (cell) handler_word->entry_point;
+ }
}
}
-namespace factor
-{
+namespace factor {
-inline static void* frame_return_address(void *frame_top)
-{
- return *(void**)frame_top;
+inline static void* frame_return_address(void* frame_top) {
+ return *(void**)frame_top;
}
-inline static void set_frame_return_address(void *frame_top, void *return_address)
-{
- *(void**)frame_top = return_address;
+inline static void set_frame_return_address(void* frame_top,
+ void* return_address) {
+ *(void**)frame_top = return_address;
}
-#define CALLSTACK_BOTTOM(ctx) (void *)(ctx->callstack_seg->end - sizeof(cell) * 5)
+#define CALLSTACK_BOTTOM(ctx) \
+ (void*)(ctx->callstack_seg->end - sizeof(cell) * 5)
inline static void flush_icache(cell start, cell len) {}
static const unsigned char call_opcode = 0xe8;
static const unsigned char jmp_opcode = 0xe9;
-inline static unsigned char call_site_opcode(cell return_address)
-{
- return *(unsigned char *)(return_address - 5);
+inline static unsigned char call_site_opcode(cell return_address) {
+ return *(unsigned char*)(return_address - 5);
}
-inline static void check_call_site(cell return_address)
-{
- unsigned char opcode = call_site_opcode(return_address);
- FACTOR_ASSERT(opcode == call_opcode || opcode == jmp_opcode);
- (void)opcode; // suppress warning when compiling without assertions
+inline static void check_call_site(cell return_address) {
+ unsigned char opcode = call_site_opcode(return_address);
+ FACTOR_ASSERT(opcode == call_opcode || opcode == jmp_opcode);
+ (void) opcode; // suppress warning when compiling without assertions
}
-inline static void *get_call_target(cell return_address)
-{
- check_call_site(return_address);
- return (void *)(*(int *)(return_address - 4) + return_address);
+inline static void* get_call_target(cell return_address) {
+ check_call_site(return_address);
+ return (void*)(*(int*)(return_address - 4) + return_address);
}
-inline static void set_call_target(cell return_address, void *target)
-{
- check_call_site(return_address);
- *(int *)(return_address - 4) = (u32)((cell)target - return_address);
+inline static void set_call_target(cell return_address, void* target) {
+ check_call_site(return_address);
+ *(int*)(return_address - 4) = (u32)((cell) target - return_address);
}
-inline static bool tail_call_site_p(cell return_address)
-{
- switch(call_site_opcode(return_address))
- {
- case jmp_opcode: return true;
- case call_opcode: return false;
- default: abort(); return false;
- }
+inline static bool tail_call_site_p(cell return_address) {
+ switch (call_site_opcode(return_address)) {
+ case jmp_opcode:
+ return true;
+ case call_opcode:
+ return false;
+ default:
+ abort();
+ return false;
+ }
}
-inline static unsigned int fpu_status(unsigned int status)
-{
- unsigned int r = 0;
-
- if (status & 0x01)
- r |= FP_TRAP_INVALID_OPERATION;
- if (status & 0x04)
- r |= FP_TRAP_ZERO_DIVIDE;
- if (status & 0x08)
- r |= FP_TRAP_OVERFLOW;
- if (status & 0x10)
- r |= FP_TRAP_UNDERFLOW;
- if (status & 0x20)
- r |= FP_TRAP_INEXACT;
-
- return r;
+inline static unsigned int fpu_status(unsigned int status) {
+ unsigned int r = 0;
+
+ if (status & 0x01)
+ r |= FP_TRAP_INVALID_OPERATION;
+ if (status & 0x04)
+ r |= FP_TRAP_ZERO_DIVIDE;
+ if (status & 0x08)
+ r |= FP_TRAP_OVERFLOW;
+ if (status & 0x10)
+ r |= FP_TRAP_UNDERFLOW;
+ if (status & 0x20)
+ r |= FP_TRAP_INEXACT;
+
+ return r;
}
}