| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | /* Parts of this file were snarfed from SBCL src/runtime/ppc-assem.S, which is | 
					
						
							|  |  |  | in the public domain. */ | 
					
						
							|  |  |  | #include "asm.h" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Note that the XT is passed to the quotation in r11 */ | 
					
						
							|  |  |  | #define CALL_OR_JUMP_QUOT \ | 
					
						
							| 
									
										
										
										
											2008-11-05 05:20:35 -05:00
										 |  |  | 	lwz r11,9(r3)	   /* load quotation-xt slot */ XX \ | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define CALL_QUOT \ | 
					
						
							| 
									
										
										
										
											2008-11-05 05:20:35 -05:00
										 |  |  | 	CALL_OR_JUMP_QUOT XX \ | 
					
						
							|  |  |  | 	mtlr r11	   /* prepare to call XT with quotation in r3 */ XX \ | 
					
						
							|  |  |  | 	blrl		   /* go */ | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define JUMP_QUOT \ | 
					
						
							| 
									
										
										
										
											2008-11-05 05:20:35 -05:00
										 |  |  | 	CALL_OR_JUMP_QUOT XX \ | 
					
						
							|  |  |  | 	mtctr r11	   /* prepare to call XT with quotation in r3 */ XX \ | 
					
						
							|  |  |  | 	bctr		   /* go */ | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define PARAM_SIZE 32 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-05 05:20:35 -05:00
										 |  |  | #define SAVED_INT_REGS_SIZE 96 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-05 05:20:35 -05:00
										 |  |  | #define SAVED_FP_REGS_SIZE 144 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define FRAME (RESERVED_SIZE + PARAM_SIZE + SAVED_INT_REGS_SIZE + SAVED_FP_REGS_SIZE + 8) | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     | 
					
						
							|  |  |  | #if defined( __APPLE__) | 
					
						
							| 
									
										
										
										
											2008-11-05 05:20:35 -05:00
										 |  |  | 	#define LR_SAVE 8 | 
					
						
							|  |  |  | 	#define RESERVED_SIZE 24 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | #else | 
					
						
							| 
									
										
										
										
											2008-11-05 05:20:35 -05:00
										 |  |  | 	#define LR_SAVE 4 | 
					
						
							|  |  |  | 	#define RESERVED_SIZE 8 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | #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) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-05 05:20:35 -05:00
										 |  |  | #define SAVE_INT(register,offset) stw register,SAVE_AT(offset)(r1) | 
					
						
							|  |  |  | #define RESTORE_INT(register,offset) lwz register,SAVE_AT(offset)(r1) | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-05 05:20:35 -05:00
										 |  |  | #define SAVE_FP(register,offset) stfd register,SAVE_AT(offset)(r1) | 
					
						
							|  |  |  | #define RESTORE_FP(register,offset) lfd register,SAVE_AT(offset)(r1) | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-25 21:23:20 -04:00
										 |  |  | #define PROLOGUE \ | 
					
						
							| 
									
										
										
										
											2008-11-05 05:20:35 -05:00
										 |  |  | 	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) | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-25 21:23:20 -04:00
										 |  |  | #define EPILOGUE \ | 
					
						
							| 
									
										
										
										
											2007-09-26 00:26:19 -04:00
										 |  |  | 	LOAD_LR(r0) XX \ | 
					
						
							| 
									
										
										
										
											2008-11-05 05:20:35 -05:00
										 |  |  | 	lwz r1,0(r1) XX	   /* destroy the stack frame */ \ | 
					
						
							|  |  |  | 	mtlr r0		   /* get ready to return */ | 
					
						
							| 
									
										
										
										
											2007-09-25 21:23:20 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-05 05:20:35 -05:00
										 |  |  | /* We have to save and restore nonvolatile registers because | 
					
						
							|  |  |  | the Factor compiler treats the entire register file as volatile. */ | 
					
						
							| 
									
										
										
										
											2007-09-25 21:23:20 -04:00
										 |  |  | DEF(void,c_to_factor,(CELL quot)): | 
					
						
							| 
									
										
										
										
											2008-11-05 05:20:35 -05:00
										 |  |  | 	PROLOGUE | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	SAVE_INT(r13,0)	   /* save GPRs */ | 
					
						
							| 
									
										
										
										
											2008-11-06 04:36:46 -05:00
										 |  |  | 	SAVE_INT(r14,1) | 
					
						
							|  |  |  | 	SAVE_INT(r15,2) | 
					
						
							| 
									
										
										
										
											2008-11-05 05:20:35 -05:00
										 |  |  | 	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_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 */ | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 	bl MANGLE(save_callstack_bottom) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-05 05:20:35 -05:00
										 |  |  | 	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 */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-06 04:36:46 -05:00
										 |  |  | 	RESTORE_INT(r28,15)   /* restore GPRs */ | 
					
						
							| 
									
										
										
										
											2008-11-05 05:20:35 -05:00
										 |  |  | 	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) | 
					
						
							| 
									
										
										
										
											2008-11-06 04:36:46 -05:00
										 |  |  | 	RESTORE_INT(r15,2) | 
					
						
							|  |  |  | 	RESTORE_INT(r14,1) | 
					
						
							| 
									
										
										
										
											2008-11-05 05:20:35 -05:00
										 |  |  | 	RESTORE_INT(r13,0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	EPILOGUE | 
					
						
							|  |  |  | 	blr | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* 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)): | 
					
						
							| 
									
										
										
										
											2008-11-05 05:20:35 -05:00
										 |  |  | 	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 */ | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | DEF(void,throw_impl,(CELL quot, F_STACK_FRAME *rewind_to)): | 
					
						
							| 
									
										
										
										
											2008-11-05 05:20:35 -05:00
										 |  |  | 	mr r1,r4	   /* compute new stack pointer */ | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 	lwz r0,LR_SAVE(r1) /* we have rewound the stack; load return address */
 | 
					
						
							|  |  |  | 	mtlr r0 | 
					
						
							| 
									
										
										
										
											2008-11-05 05:20:35 -05:00
										 |  |  | 	JUMP_QUOT	   /* call the quotation */ | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-25 21:23:20 -04:00
										 |  |  | DEF(void,lazy_jit_compile,(CELL quot)): | 
					
						
							| 
									
										
										
										
											2008-11-05 05:20:35 -05:00
										 |  |  | 	mr r4,r1	   /* save stack pointer */ | 
					
						
							| 
									
										
										
										
											2007-09-25 21:23:20 -04:00
										 |  |  | 	PROLOGUE | 
					
						
							| 
									
										
										
										
											2007-10-03 16:56:49 -04:00
										 |  |  | 	bl MANGLE(primitive_jit_compile) | 
					
						
							| 
									
										
										
										
											2007-09-25 21:23:20 -04:00
										 |  |  | 	EPILOGUE | 
					
						
							| 
									
										
										
										
											2008-11-05 05:20:35 -05:00
										 |  |  | 	JUMP_QUOT	   /* call the quotation */ | 
					
						
							| 
									
										
										
										
											2007-09-25 21:23:20 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | /* 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)): | 
					
						
							| 
									
										
										
										
											2008-11-05 05:20:35 -05:00
										 |  |  | 	/* 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 |