Kyle McMartin
2005-Nov-25 11:47 UTC
[klibc] Fix syscalls with more than four arguments on parisc
Reimplement __common_syscall in assembler. The 32-bit ABI says that the fifth and sixth arguments to the function are passed on the stack, but our syscall ABI says they are passed in %arg4 and %arg5 like the 64-bit ABI. Also, tried to optimize the code slightly by making use of the cmpb delay slot to load the errno return of -1. Signed-off-by: Kyle McMartin <kyle@parisc-linux.org> diff --git a/klibc/arch/parisc/Makefile.inc b/klibc/arch/parisc/Makefile.inc index 980a543..4fddf5f 100644 --- a/klibc/arch/parisc/Makefile.inc +++ b/klibc/arch/parisc/Makefile.inc @@ -14,6 +14,3 @@ ARCHOBJS = \ ARCHOOBJS = $(patsubst %o,%.lo,%(ARCHOBJS)) archclean: - -arch/$(ARCH)/syscall.o: arch/$(ARCH)/syscall.c - $(CC) $(CFLAGS) -ffixed-r20 -c -o $@ $< diff --git a/klibc/arch/parisc/syscall.S b/klibc/arch/parisc/syscall.S new file mode 100644 index 0000000..a4f26f5 --- /dev/null +++ b/klibc/arch/parisc/syscall.S @@ -0,0 +1,36 @@ +/* + * arch/parisc/syscall.S + * + * %r20 contains the system call number, %r2 contains whence we came + * + */ + + .text + .align 64 ; cache-width aligned + .globl __syscall_common + .type __syscall_common,@function +__syscall_common: + ldo 0x40(%sp),%sp + stw %rp,-0x54(%sp) ; save return pointer + + ldw -0x74(%sp),%r22 ; %arg4 + ldw -0x78(%sp),%r21 ; %arg5 + + ble 0x100(%sr2, %r0) ; jump to gateway page + nop ; can we move a load here? + + ldi -0x1000,%r19 ; %r19 = -4096 + sub %r0,%ret0,%r22 ; %r22 = -%ret0 + cmpb,>>=,n %r19,%ret0,1f ; if %ret0 >= -4096UL + ldi -1,%ret0 ; nullified on taken forward + + /* store %r22 to errno... */ + ldil L%errno,%r1 + ldo R%errno(%r1),%r1 + stw %r22,0(%r1) +1: + ldw -0x54(%sp),%rp ; restore return pointer + bv %r0(%rp) ; jump back + ldo -0x40(%sp),%sp + + .size __syscall_common,.-__syscall_common diff --git a/klibc/arch/parisc/syscall.c b/klibc/arch/parisc/syscall.c deleted file mode 100644 index 99ef5fe..0000000 --- a/klibc/arch/parisc/syscall.c +++ /dev/null @@ -1,29 +0,0 @@ -/* - * arch/parisc/syscall.c - * - * This function is called from a stub with %r20 already set up. - * Compile this function with -ffixed-r20 so that it doesn't clobber - * this register by mistake. - */ - -#include <klibc/compiler.h> -#include <errno.h> - -long __syscall_common(long a0, long a1, long a2, long a3, long a4, long a5) -{ - register unsigned long rv asm ("r28"); - - asm volatile("\tble 0x100(%%sr2, %%r0)\n" - : "=r" (rv) - : "r" (a0), "r" (a1), "r" (a2), "r" (a3), "r" (a4), "r" (a5) - : "%r1", "%r2", "%r29", "%r31"); - - if ( __unlikely(rv >= -4095UL) ) { - errno = -rv; - return -1L; - } else { - return (long)rv; - } -} - -