diff options
Diffstat (limited to 'libc/sysdeps/linux/mips/clone.S')
-rw-r--r-- | libc/sysdeps/linux/mips/clone.S | 32 |
1 files changed, 24 insertions, 8 deletions
diff --git a/libc/sysdeps/linux/mips/clone.S b/libc/sysdeps/linux/mips/clone.S index 7e3838a35..716cd993f 100644 --- a/libc/sysdeps/linux/mips/clone.S +++ b/libc/sysdeps/linux/mips/clone.S @@ -38,11 +38,16 @@ clone: .frame sp, 4*SZREG, sp #ifdef __PIC__ +#if _MIPS_SIM == _MIPS_SIM_ABI32 .set noreorder .cpload $25 .set reorder subu sp,32 .cprestore 16 +#else /* N32 */ + PTR_SUBU sp,32 /* fn, arg, gp, pad */ + .cpsetup $25, 16, clone +#endif /* N32 */ #else subu sp,32 #endif @@ -53,9 +58,12 @@ clone: beqz a0,error /* No NULL function pointers. */ beqz a1,error /* No NULL stack pointers. */ - subu a1,32 /* Reserve argument save space. */ - sw a0,0(a1) /* Save function pointer. */ - sw a3,4(a1) /* Save argument pointer. */ +#if _MIPS_SIM != _MIPS_SIM_ABI32 + and a1,~(16-1) /* force alignment */ +#endif + PTR_SUBU a1,32 /* Reserve argument save space. */ + PTR_S a0,0(a1) /* Save function pointer. */ + PTR_S a3,PTRSIZE(a1) /* Save argument pointer. */ /* Do the system call */ @@ -67,19 +75,25 @@ clone: beqz v0,__thread_start /* Successful return from the parent */ - addiu sp,32 +#if _MIPS_SIM != _MIPS_SIM_ABI32 + .cpreturn +#endif + PTR_ADDU sp,32 j $31 ; nop /* Something bad happened -- no child created */ error: - addiu sp,32 +#if _MIPS_SIM != _MIPS_SIM_ABI32 + .cpreturn +#endif + PTR_ADDU sp,32 /* uClibc change -- start */ move a0,v0 /* Pass return val to C function. */ /* uClibc change -- stop */ #ifdef __PIC__ - la t9,__syscall_error + PTR_LA t9,__syscall_error jr t9 #else j __syscall_error @@ -95,12 +109,14 @@ error: .ent __thread_start, 0; __thread_start: +#if _MIPS_SIM == _MIPS_SIM_ABI32 /* cp is already loaded. */ .cprestore 16 +#endif /* The stackframe has been created on entry of clone(). */ /* Restore the arg for user's function. */ - lw t9,0(sp) /* Function pointer. */ - lw a0,4(sp) /* Argument pointer. */ + PTR_L t9,0(sp) /* Function pointer. */ + PTR_L a0,PTRSIZE(sp) /* Argument pointer. */ /* Call the user's function. */ jal t9 |