mirror of git://git.musl-libc.org/musl
implement inline 5- and 6-argument syscalls for mips
the OABI passes these on the stack, using the convention that their position on the stack is as if the first four arguments (in registers) also had stack slots. originally this was deemed too awkward to do inline, falling back to external __syscall, but it's not that bad and now that external __syscall is being removed, it's necessary.
This commit is contained in:
parent
6aeb9c6703
commit
dcb18bea61
|
@ -3,8 +3,6 @@
|
||||||
((union { long long ll; long l[2]; }){ .ll = x }).l[1]
|
((union { long long ll; long l[2]; }){ .ll = x }).l[1]
|
||||||
#define __SYSCALL_LL_O(x) 0, __SYSCALL_LL_E((x))
|
#define __SYSCALL_LL_O(x) 0, __SYSCALL_LL_E((x))
|
||||||
|
|
||||||
hidden long (__syscall)(long, ...);
|
|
||||||
|
|
||||||
#define SYSCALL_RLIM_INFINITY (-1UL/2)
|
#define SYSCALL_RLIM_INFINITY (-1UL/2)
|
||||||
|
|
||||||
#if _MIPSEL || __MIPSEL || __MIPSEL__
|
#if _MIPSEL || __MIPSEL || __MIPSEL__
|
||||||
|
@ -104,8 +102,22 @@ static inline long __syscall4(long n, long a, long b, long c, long d)
|
||||||
|
|
||||||
static inline long __syscall5(long n, long a, long b, long c, long d, long e)
|
static inline long __syscall5(long n, long a, long b, long c, long d, long e)
|
||||||
{
|
{
|
||||||
long r2 = (__syscall)(n, a, b, c, d, e);
|
register long r4 __asm__("$4") = a;
|
||||||
if (r2 > -4096UL) return r2;
|
register long r5 __asm__("$5") = b;
|
||||||
|
register long r6 __asm__("$6") = c;
|
||||||
|
register long r7 __asm__("$7") = d;
|
||||||
|
register long r8 __asm__("$8") = e;
|
||||||
|
register long r2 __asm__("$2");
|
||||||
|
__asm__ __volatile__ (
|
||||||
|
"subu $sp,$sp,32 ; sw $8,16($sp) ; "
|
||||||
|
"addu $2,$0,%3 ; syscall ;"
|
||||||
|
"addu $sp,$sp,32"
|
||||||
|
: "=&r"(r2), "=r"(r7), "+r"(r8)
|
||||||
|
: "ir"(n), "0"(r2), "1"(r7), "r"(r4), "r"(r5), "r"(r6)
|
||||||
|
: "$1", "$3", "$9", "$10", "$11", "$12", "$13",
|
||||||
|
"$14", "$15", "$24", "$25", "hi", "lo", "memory");
|
||||||
|
if (r7) return -r2;
|
||||||
|
long ret = r2;
|
||||||
if (n == SYS_stat64 || n == SYS_fstat64 || n == SYS_lstat64) __stat_fix(b);
|
if (n == SYS_stat64 || n == SYS_fstat64 || n == SYS_lstat64) __stat_fix(b);
|
||||||
if (n == SYS_fstatat64) __stat_fix(c);
|
if (n == SYS_fstatat64) __stat_fix(c);
|
||||||
return r2;
|
return r2;
|
||||||
|
@ -113,8 +125,23 @@ static inline long __syscall5(long n, long a, long b, long c, long d, long e)
|
||||||
|
|
||||||
static inline long __syscall6(long n, long a, long b, long c, long d, long e, long f)
|
static inline long __syscall6(long n, long a, long b, long c, long d, long e, long f)
|
||||||
{
|
{
|
||||||
long r2 = (__syscall)(n, a, b, c, d, e, f);
|
register long r4 __asm__("$4") = a;
|
||||||
if (r2 > -4096UL) return r2;
|
register long r5 __asm__("$5") = b;
|
||||||
|
register long r6 __asm__("$6") = c;
|
||||||
|
register long r7 __asm__("$7") = d;
|
||||||
|
register long r8 __asm__("$8") = e;
|
||||||
|
register long r9 __asm__("$9") = f;
|
||||||
|
register long r2 __asm__("$2");
|
||||||
|
__asm__ __volatile__ (
|
||||||
|
"subu $sp,$sp,32 ; sw $8,16($sp) ; sw $9,20($sp) ; "
|
||||||
|
"addu $2,$0,%4 ; syscall ;"
|
||||||
|
"addu $sp,$sp,32"
|
||||||
|
: "=&r"(r2), "=r"(r7), "+r"(r8), "+r"(r9)
|
||||||
|
: "ir"(n), "0"(r2), "1"(r7), "r"(r4), "r"(r5), "r"(r6)
|
||||||
|
: "$1", "$3", "$10", "$11", "$12", "$13",
|
||||||
|
"$14", "$15", "$24", "$25", "hi", "lo", "memory");
|
||||||
|
if (r7) return -r2;
|
||||||
|
long ret = r2;
|
||||||
if (n == SYS_stat64 || n == SYS_fstat64 || n == SYS_lstat64) __stat_fix(b);
|
if (n == SYS_stat64 || n == SYS_fstat64 || n == SYS_lstat64) __stat_fix(b);
|
||||||
if (n == SYS_fstatat64) __stat_fix(c);
|
if (n == SYS_fstatat64) __stat_fix(c);
|
||||||
return r2;
|
return r2;
|
||||||
|
|
Loading…
Reference in New Issue