FreeBSD/sys/mips/mips/pm_machdep.c
/*
 * Clear registers on exec
 * $sp is set to the stack pointer passed in.  $pc is set to the entry
 * point given by the exec_package passed in, as is $t9 (used for PIC
 * code by the MIPS elf abi).
 */
Clear registers on exec
$sp is set to the stack pointer passed in.  $pc is set to the entry
point given by the exec_package passed in, as is $t9 (used for PIC
code by the MIPS elf abi).
Clear registers on exec $sp is set to the stack pointer passed in . $pc is set to the entry point given by the exec_package passed in as is $t9 ( used for PIC code by the MIPS elf abi ) .
void
exec_setregs(struct thread *td, struct image_params *imgp, u_long stack)
{
	bzero((caddr_t)td->td_frame, sizeof(struct trapframe));
	td->td_frame->sp = ((register_t) stack) & ~(sizeof(__int64_t) - 1);
#if !defined(__mips_n64)
	td->td_frame->sp -= 65536;
#endif
	td->td_frame->pc = imgp->entry_addr & ~3;
	td->td_frame->t9 = imgp->entry_addr & ~3; 
	td->td_frame->sr = MIPS_SR_KSU_USER | MIPS_SR_EXL | MIPS_SR_INT_IE |
	    (mips_rd_status() & MIPS_SR_INT_MASK);
#if defined(__mips_n32) 
	td->td_frame->sr |= MIPS_SR_PX;
#elif  defined(__mips_n64)
	td->td_frame->sr |= MIPS_SR_PX | MIPS_SR_UX | MIPS_SR_KX;
#endif
	td->td_frame->a0 = (register_t) stack;
	td->td_frame->a1 = 0;
	td->td_frame->a2 = 0;
	td->td_frame->a3 = (register_t)imgp->ps_strings;
	td->td_md.md_flags &= ~MDTD_FPUSED;
	if (PCPU_GET(fpcurthread) == td)
	    PCPU_SET(fpcurthread, (struct thread *)0);
	td->td_md.md_ss_addr = 0;
}
void exec_setregs ( struct thread * td , struct image_params * imgp , u_long stack ) { bzero ( ( caddr_t ) td -> td_frame , sizeof ( struct trapframe ) ) ; td -> td_frame -> sp = ( ( register_t ) stack ) & ~ ( sizeof ( __int64_t ) - 1 ) ; #if ! defined ( __mips_n64 ) td -> td_frame -> sp -= 65536 ; #endif td -> td_frame -> pc = imgp -> entry_addr & ~ 3 ; td -> td_frame -> t9 = imgp -> entry_addr & ~ 3 ; td -> td_frame -> sr = MIPS_SR_KSU_USER | MIPS_SR_EXL | MIPS_SR_INT_IE | ( mips_rd_status ( ) & MIPS_SR_INT_MASK ) ; #if defined ( __mips_n32 ) td -> td_frame -> sr |= MIPS_SR_PX ; #elif defined ( __mips_n64 ) td -> td_frame -> sr |= MIPS_SR_PX | MIPS_SR_UX | MIPS_SR_KX ; #endif td -> td_frame -> a0 = ( register_t ) stack ; td -> td_frame -> a1 = 0 ; td -> td_frame -> a2 = 0 ; td -> td_frame -> a3 = ( register_t ) imgp -> ps_strings ; td -> td_md . md_flags &= ~ MDTD_FPUSED ; if ( PCPU_GET ( fpcurthread ) == td ) PCPU_SET ( fpcurthread , ( struct thread * ) 0 ) ; td -> td_md . md_ss_addr = 0 ; }
Clear registers on exec
 $sp is set to the stack pointer passed in.
Clear registers on exec $sp is set to the stack pointer passed in .
/*
	 * The stack pointer has to be aligned to accommodate the largest
	 * datatype at minimum.  This probably means it should be 16-byte
	 * aligned, but for now we're 8-byte aligning it.
	 */ /*
	 * If we're running o32 or n32 programs but have 64-bit registers,
	 * GCC may use stack-relative addressing near the top of user
	 * address space that, due to sign extension, will yield an
	 * invalid address.  For instance, if sp is 0x7fffff00 then GCC
	 * might do something like this to load a word from 0x7ffffff0:
	 *
	 * 	addu	sp, sp, 32768
	 * 	lw	t0, -32528(sp)
	 *
	 * On systems with 64-bit registers, sp is sign-extended to
	 * 0xffffffff80007f00 and the load is instead done from
	 * 0xffffffff7ffffff0.
	 *
	 * To prevent this, we subtract 64K from the stack pointer here.
	 *
	 * For consistency, we should just always do this unless we're
	 * running n64 programs.  For now, since we don't support
	 * COMPAT_FREEBSD32 on n64 kernels, we just do it unless we're
	 * running n64 kernels.
	 */ /* abicall req */ /*
	 * FREEBSD_DEVELOPERS_FIXME:
	 * Setup any other CPU-Specific registers (Not MIPS Standard)
	 * and/or bits in other standard MIPS registers (if CPU-Specific)
	 *  that are needed.
	 */ /*
	 * Set up arguments for the rtld-capable crt0:
	 *	a0	stack pointer
	 *	a1	rtld cleanup (filled in by dynamic loader)
	 *	a2	rtld object (filled in by dynamic loader)
	 *	a3	ps_strings
	 */