-! Copyright (C) 2005, 2008 Slava Pestov.
+! Copyright (C) 2005, 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors assocs sequences kernel combinators make math
math.order math.ranges system namespaces locals layouts words
-alien alien.c-types cpu.architecture cpu.ppc.assembler
-compiler.cfg.registers compiler.cfg.instructions
+alien alien.c-types literals cpu.architecture cpu.ppc.assembler
+literals compiler.cfg.registers compiler.cfg.instructions
compiler.constants compiler.codegen compiler.codegen.fixup
compiler.cfg.intrinsics compiler.cfg.stack-frame ;
IN: cpu.ppc
! PowerPC register assignments:
-! r2-r27: integer vregs
-! r28: integer scratch
-! r29: data stack
-! r30: retain stack
+! r2-r12: integer vregs
+! r15-r29
+! r30: integer scratch
! f0-f29: float vregs
-! f30, f31: float scratch
+! f30: float scratch
enable-float-intrinsics
M: ppc machine-registers
{
- { int-regs T{ range f 2 26 1 } }
- { double-float-regs T{ range f 0 29 1 } }
+ { int-regs $[ 2 12 [a,b] 15 29 [a,b] append ] }
+ { double-float-regs $[ 0 29 [a,b] ] }
} ;
-CONSTANT: scratch-reg 28
+CONSTANT: scratch-reg 30
CONSTANT: fp-scratch-reg 30
M: ppc two-operand? f ;
M: ppc %alien-global ( register symbol dll -- )
[ 0 swap LOAD32 ] 2dip rc-absolute-ppc-2/2 rel-dlsym ;
-CONSTANT: ds-reg 29
-CONSTANT: rs-reg 30
+CONSTANT: ds-reg 13
+CONSTANT: rs-reg 14
GENERIC: loc-reg ( loc -- reg )
in the public domain. */
#include "asm.h"
-#define DS_REG r29
+#define DS_REG r13
DEF(void,primitive_fixnum_add,(void)):
lwz r3,0(DS_REG)
/* Note that the XT is passed to the quotation in r11 */
#define CALL_OR_JUMP_QUOT \
- lwz r11,14(r3) /* load quotation-xt slot */ XX \
+ lwz r11,16(r3) /* load quotation-xt slot */ XX \
#define CALL_QUOT \
CALL_OR_JUMP_QUOT XX \
DEF(void,c_to_factor,(CELL quot)):
PROLOGUE
- SAVE_INT(r13,0) /* save GPRs */
- SAVE_INT(r14,1)
- SAVE_INT(r15,2)
- SAVE_INT(r16,3)
- SAVE_INT(r17,4)
- SAVE_INT(r18,5)
- SAVE_INT(r19,6)
- SAVE_INT(r20,7)
- SAVE_INT(r21,8)
- SAVE_INT(r22,9)
- SAVE_INT(r23,10)
- SAVE_INT(r24,11)
- SAVE_INT(r25,12)
- SAVE_INT(r26,13)
- SAVE_INT(r27,14)
- SAVE_INT(r28,15)
+ SAVE_INT(r15,0) /* save GPRs */
+ SAVE_INT(r16,1)
+ SAVE_INT(r17,2)
+ SAVE_INT(r18,3)
+ SAVE_INT(r19,4)
+ SAVE_INT(r20,5)
+ SAVE_INT(r21,6)
+ SAVE_INT(r22,7)
+ SAVE_INT(r23,8)
+ SAVE_INT(r24,9)
+ SAVE_INT(r25,10)
+ SAVE_INT(r26,11)
+ SAVE_INT(r27,12)
+ SAVE_INT(r28,13)
+ SAVE_INT(r29,14)
+ SAVE_INT(r30,15)
SAVE_INT(r31,16)
SAVE_FP(f14,20) /* save FPRs */
RESTORE_FP(f14,20) /* save FPRs */
RESTORE_INT(r31,16) /* restore GPRs */
- RESTORE_INT(r28,15)
- RESTORE_INT(r27,14)
- RESTORE_INT(r26,13)
- RESTORE_INT(r25,12)
- RESTORE_INT(r24,11)
- RESTORE_INT(r23,10)
- RESTORE_INT(r22,9)
- RESTORE_INT(r21,8)
- RESTORE_INT(r20,7)
- RESTORE_INT(r19,6)
- RESTORE_INT(r18,5)
- RESTORE_INT(r17,4)
- RESTORE_INT(r16,3)
- RESTORE_INT(r15,2)
- RESTORE_INT(r14,1)
- RESTORE_INT(r13,0)
+ RESTORE_INT(r30,15)
+ RESTORE_INT(r29,14)
+ RESTORE_INT(r28,13)
+ RESTORE_INT(r27,12)
+ RESTORE_INT(r26,11)
+ RESTORE_INT(r25,10)
+ RESTORE_INT(r24,9)
+ RESTORE_INT(r23,8)
+ RESTORE_INT(r22,7)
+ RESTORE_INT(r21,6)
+ RESTORE_INT(r20,5)
+ RESTORE_INT(r19,4)
+ RESTORE_INT(r18,3)
+ RESTORE_INT(r17,2)
+ RESTORE_INT(r16,1)
+ RESTORE_INT(r15,0)
EPILOGUE
blr
sync /* finish up */
isync
blr
+
+DEF(void,primitive_inline_cache_miss,(void)):
+ mflr r3
+ PROLOGUE
+ bl MANGLE(inline_cache_miss)
+ EPILOGUE
+ mtctr r3
+ bctr
{
#define FACTOR_CPU_STRING "ppc"
-#define VM_ASM_API
+#define VM_ASM_API VM_C_API
-register cell ds asm("r29");
-register cell rs asm("r30");
+register cell ds asm("r13");
+register cell rs asm("r14");
-void c_to_factor(cell quot);
-void undefined(cell word);
-void set_callstack(stack_frame *to, stack_frame *from, cell length, void *memcpy);
-void throw_impl(cell quot, stack_frame *rewind);
-void lazy_jit_compile(cell quot);
-void flush_icache(cell start, cell len);
+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));
}
{
/* Find the call target. */
void *old_xt = get_call_target(return_address);
+ check_code_pointer((cell)old_xt);
+
code_block *old_block = (code_block *)old_xt - 1;
cell old_type = old_block->type;