about summary refs log tree commit diff
path: root/arch/mips/syscall_arch.h
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2012-09-09 01:01:19 -0400
committerRich Felker <dalias@aerifal.cx>2012-09-09 01:01:19 -0400
commit328810d32524e4928fec50b57e37e1bf330b2e40 (patch)
tree1db4efb8d84abde9da0e52cb0327abf4ff27a33d /arch/mips/syscall_arch.h
parentbe48e22b424b6f858da0151a0b3b68bdb96b41ca (diff)
downloadmusl-328810d32524e4928fec50b57e37e1bf330b2e40.tar.gz
musl-328810d32524e4928fec50b57e37e1bf330b2e40.tar.xz
musl-328810d32524e4928fec50b57e37e1bf330b2e40.zip
inline syscall support for mips
this drastically reduces the size of some functions which are purely
syscall wrappers.

disabled for clang due to known bugs satisfying register constraints.
Diffstat (limited to 'arch/mips/syscall_arch.h')
-rw-r--r--arch/mips/syscall_arch.h57
1 files changed, 57 insertions, 0 deletions
diff --git a/arch/mips/syscall_arch.h b/arch/mips/syscall_arch.h
index 68e8dce3..f3df2dcd 100644
--- a/arch/mips/syscall_arch.h
+++ b/arch/mips/syscall_arch.h
@@ -5,6 +5,61 @@
 
 #define __SYSCALL_SSLEN 16
 
+#ifndef __clang__
+
+#define __asm_syscall(...) do { \
+	register long r2 __asm__("$2"); \
+	register long r7 __asm__("$7"); \
+	__asm__ __volatile__ ( \
+	"move $2,%2 ; syscall" \
+	: "=&r"(r2), "=r"(r7) : __VA_ARGS__ \
+	: "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", \
+	  "$14", "$15", "$24", "hi", "lo", "memory"); \
+	return r7 ? -r2 : r2; \
+	} while (0)
+
+static inline long __syscall0(long n)
+{
+	register long r25 __asm__("$25") = n;
+	__asm_syscall("r"(r25));
+}
+
+static inline long __syscall1(long n, long a)
+{
+	register long r25 __asm__("$25") = n;
+	register long r4 __asm__("$4") = a;
+	__asm_syscall("r"(r25), "r"(r4));
+}
+
+static inline long __syscall2(long n, long a, long b)
+{
+	register long r25 __asm__("$25") = n;
+	register long r4 __asm__("$4") = a;
+	register long r5 __asm__("$5") = b;
+	__asm_syscall("r"(r25), "r"(r4), "r"(r5));
+}
+
+static inline long __syscall3(long n, long a, long b, long c)
+{
+	register long r25 __asm__("$25") = n;
+	register long r4 __asm__("$4") = a;
+	register long r5 __asm__("$5") = b;
+	register long r6 __asm__("$6") = c;
+	__asm_syscall("r"(r25), "r"(r4), "r"(r5), "r"(r6));
+}
+
+static inline long __syscall4(long n, long a, long b, long c, long d)
+{
+	register long r25 __asm__("$25") = n;
+	register long r4 __asm__("$4") = a;
+	register long r5 __asm__("$5") = b;
+	register long r6 __asm__("$6") = c;
+	register long r7 __asm__("$7") = d;
+	__asm_syscall("r"(r25), "r"(r4), "r"(r5), "r"(r6), "r"(r7));
+}
+
+#else
+
 static inline long __syscall0(long n)
 {
 	return (__syscall)(n);
@@ -30,6 +85,8 @@ static inline long __syscall4(long n, long a, long b, long c, long d)
 	return (__syscall)(n, a, b, c, d);
 }
 
+#endif
+
 static inline long __syscall5(long n, long a, long b, long c, long d, long e)
 {
 	return (__syscall)(n, a, b, c, d, e);