[klibc] Fix syscalls with more than four arguments on parisc

Kyle McMartin kyle at parisc-linux.org
Fri Nov 25 11:44:54 PST 2005


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 at 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, at 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;
-  }
-}
-
-  



More information about the klibc mailing list