factor/vm/cpu-ppc.S

237 lines
5.7 KiB
ArmAsm
Executable File

/* Parts of this file were snarfed from SBCL src/runtime/ppc-assem.S, which is
in the public domain. */
#include "asm.h"
#define DS_REG r29
DEF(void,primitive_fixnum_add,(void)):
lwz r3,0(DS_REG)
lwz r4,-4(DS_REG)
subi DS_REG,DS_REG,4
li r0,0
mtxer r0
addo. r5,r3,r4
bso add_overflow
stw r5,0(DS_REG)
blr
add_overflow:
b MANGLE(overflow_fixnum_add)
DEF(void,primitive_fixnum_subtract,(void)):
lwz r3,-4(DS_REG)
lwz r4,0(DS_REG)
subi DS_REG,DS_REG,4
li r0,0
mtxer r0
subfo. r5,r4,r3
bso sub_overflow
stw r5,0(DS_REG)
blr
sub_overflow:
b MANGLE(overflow_fixnum_subtract)
DEF(void,primitive_fixnum_multiply,(void)):
lwz r3,0(DS_REG)
lwz r4,-4(DS_REG)
subi DS_REG,DS_REG,4
srawi r3,r3,3
mullwo. r5,r3,r4
bso multiply_overflow
stw r5,0(DS_REG)
blr
multiply_overflow:
srawi r4,r4,3
b MANGLE(overflow_fixnum_multiply)
/* 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 \
#define CALL_QUOT \
CALL_OR_JUMP_QUOT XX \
mtlr r11 /* prepare to call XT with quotation in r3 */ XX \
blrl /* go */
#define JUMP_QUOT \
CALL_OR_JUMP_QUOT XX \
mtctr r11 /* prepare to call XT with quotation in r3 */ XX \
bctr /* go */
#define PARAM_SIZE 32
#define SAVED_INT_REGS_SIZE 96
#define SAVED_FP_REGS_SIZE 144
#define FRAME (RESERVED_SIZE + PARAM_SIZE + SAVED_INT_REGS_SIZE + SAVED_FP_REGS_SIZE + 8)
#if defined( __APPLE__)
#define LR_SAVE 8
#define RESERVED_SIZE 24
#else
#define LR_SAVE 4
#define RESERVED_SIZE 8
#endif
#define SAVE_LR(reg) stw reg,(LR_SAVE + FRAME)(r1)
#define LOAD_LR(reg) lwz reg,(LR_SAVE + FRAME)(r1)
#define SAVE_AT(offset) (RESERVED_SIZE + PARAM_SIZE + 4 * offset)
#define SAVE_INT(register,offset) stw register,SAVE_AT(offset)(r1)
#define RESTORE_INT(register,offset) lwz register,SAVE_AT(offset)(r1)
#define SAVE_FP(register,offset) stfd register,SAVE_AT(offset)(r1)
#define RESTORE_FP(register,offset) lfd register,SAVE_AT(offset)(r1)
#define PROLOGUE \
mflr r0 XX /* get caller's return address */ \
stwu r1,-FRAME(r1) XX /* create a stack frame to hold non-volatile registers */ \
SAVE_LR(r0)
#define EPILOGUE \
LOAD_LR(r0) XX \
lwz r1,0(r1) XX /* destroy the stack frame */ \
mtlr r0 /* get ready to return */
/* We have to save and restore nonvolatile registers because
the Factor compiler treats the entire register file as volatile. */
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(r31,16)
SAVE_FP(f14,20) /* save FPRs */
SAVE_FP(f15,22)
SAVE_FP(f16,24)
SAVE_FP(f17,26)
SAVE_FP(f18,28)
SAVE_FP(f19,30)
SAVE_FP(f20,32)
SAVE_FP(f21,34)
SAVE_FP(f22,36)
SAVE_FP(f23,38)
SAVE_FP(f24,40)
SAVE_FP(f25,42)
SAVE_FP(f26,44)
SAVE_FP(f27,46)
SAVE_FP(f28,48)
SAVE_FP(f29,50)
SAVE_FP(f30,52)
SAVE_FP(f31,54)
SAVE_INT(r3,19) /* save quotation since we're about to mangle it */
mr r3,r1 /* pass call stack pointer as an argument */
bl MANGLE(save_callstack_bottom)
RESTORE_INT(r3,19) /* restore quotation */
CALL_QUOT
RESTORE_FP(f31,54)
RESTORE_FP(f30,52)
RESTORE_FP(f29,50)
RESTORE_FP(f28,48)
RESTORE_FP(f27,46)
RESTORE_FP(f26,44)
RESTORE_FP(f25,42)
RESTORE_FP(f24,40)
RESTORE_FP(f23,38)
RESTORE_FP(f22,36)
RESTORE_FP(f21,34)
RESTORE_FP(f20,32)
RESTORE_FP(f19,30)
RESTORE_FP(f18,28)
RESTORE_FP(f17,26)
RESTORE_FP(f16,24)
RESTORE_FP(f15,22)
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)
EPILOGUE
blr
/* We pass a function pointer to memcpy in r6 to work around a Mac OS X ABI
limitation which would otherwise require us to do a bizzaro PC-relative
trampoline to retrieve the function address */
DEF(void,set_callstack,(F_STACK_FRAME *to, F_STACK_FRAME *from, CELL length, void *memcpy)):
sub r1,r3,r5 /* compute new stack pointer */
mr r3,r1 /* start of destination of memcpy() */
stwu r1,-64(r1) /* setup fake stack frame for memcpy() */
mtlr r6 /* prepare to call memcpy() */
blrl /* go */
lwz r1,0(r1) /* tear down fake stack frame */
lwz r0,LR_SAVE(r1) /* we have restored the stack; load return address */
mtlr r0 /* prepare to return to restored callstack */
blr /* go */
DEF(void,throw_impl,(CELL quot, F_STACK_FRAME *rewind_to)):
mr r1,r4 /* compute new stack pointer */
lwz r0,LR_SAVE(r1) /* we have rewound the stack; load return address */
mtlr r0
JUMP_QUOT /* call the quotation */
DEF(void,lazy_jit_compile,(CELL quot)):
mr r4,r1 /* save stack pointer */
PROLOGUE
bl MANGLE(lazy_jit_compile_impl)
EPILOGUE
JUMP_QUOT /* call the quotation */
/* Thanks to Joshua Grams for this code.
On PowerPC processors, we must flush the instruction cache manually
after writing to the code heap. */
DEF(void,flush_icache,(void *start, int len)):
/* compute number of cache lines to flush */
add r4,r4,r3
clrrwi r3,r3,5 /* align addr to next lower cache line boundary */
sub r4,r4,r3 /* then n_lines = (len + 0x1f) / 0x20 */
addi r4,r4,0x1f
srwi. r4,r4,5 /* note '.' suffix */
beqlr /* if n_lines == 0, just return. */
mtctr r4 /* flush cache lines */
0: dcbf 0,r3 /* for each line... */
sync
icbi 0,r3
addi r3,r3,0x20
bdnz 0b
sync /* finish up */
isync
blr