diff options
Diffstat (limited to 'newlib/libc/sys/sparc64/sys/syscallasm.h')
-rw-r--r-- | newlib/libc/sys/sparc64/sys/syscallasm.h | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/newlib/libc/sys/sparc64/sys/syscallasm.h b/newlib/libc/sys/sparc64/sys/syscallasm.h new file mode 100644 index 00000000000..d882a9e318b --- /dev/null +++ b/newlib/libc/sys/sparc64/sys/syscallasm.h @@ -0,0 +1,87 @@ +#ifndef _SYSCALLASM_H_ +#define _SYSCALLASM_H_ + +/* + * This file defines the system calls for SPARC for the assembler. + * Anything C-ish is not allowed in this file. + * C files should include syscall.h. + */ + +#include <sys/syscall.h> + +/* Some macros for writing assember syscall stubs. */ + +#ifdef __svr4__ +#define TEXT_SECTION .section ".text" +#define DATA_SECTION .section ".data" +#define ALIGN(x) .align x +#define GLOBAL(sym) .global sym +#define WORD(x) .long x +#define ASM_SYMBOL(name) name +#define ASM_PRIVATE_SYMBOL(name) _##name +#define SYSCALL_TRAP 8 +#else +#define TEXT_SECTION .text +#define DATA_SECTION .data +#define ALIGN(x) .align x +#define GLOBAL(sym) .global sym +#define WORD(x) .word x +#define ASM_SYMBOL(name) _##name +#define ASM_PRIVATE_SYMBOL(name) name +#define SYSCALL_TRAP 0 +#endif + +#define defsyscall(name, n) \ + TEXT_SECTION ; \ + ALIGN (4) ; \ + GLOBAL (ASM_SYMBOL (name)) ; \ +ASM_SYMBOL (name): \ + mov n,%g1 ; \ + ta %icc,SYSCALL_TRAP ; \ + bcc noerr ; \ + sethi %hi (ASM_PRIVATE_SYMBOL (cerror)),%g1 ; \ + or %g1,%lo (ASM_PRIVATE_SYMBOL (cerror)),%g1 ; \ + jmpl %g1+%g0,%g0 ; \ + nop ; \ +noerr: \ + jmpl %o7+8,%g0 ; \ + nop + +/* Support for reentrant syscalls. The "struct _reent *" arg is always the + the first one. After that we allow up to four additional args. We could + allow more, but that's all we need for now. + + It may seem inefficient to have the reent arg be the first one as it means + copying all the other args into place (as opposed to making the reent arg + the last one in which case there wouldn't be any copying). I chose a clean + design over an extra four instructions in a system call. All other + reentrant functions use the first arg this way. */ + +#define defsyscall_r(name, n) \ + TEXT_SECTION ; \ + ALIGN (4) ; \ + GLOBAL (ASM_SYMBOL (name)) ; \ +ASM_SYMBOL (name): \ + mov n,%g1 ; \ + mov %o0,%o5 ; \ + mov %o1,%o0 ; \ + mov %o2,%o1 ; \ + mov %o3,%o2 ; \ + mov %o4,%o3 ; \ + ta %icc,SYSCALL_TRAP ; \ + bcc noerr ; \ + sethi %hi (ASM_PRIVATE_SYMBOL (cerror_r)),%g1 ; \ + or %g1,%lo (ASM_PRIVATE_SYMBOL (cerror_r)),%g1 ; \ + jmpl %g1+%g0,%g0 ; \ + mov %o5,%o1 ; \ +noerr: \ + jmpl %o7+8,%g0 ; \ + nop + +#define seterrno() \ + sethi %hi (ASM_PRIVATE_SYMBOL (cerror)),%g1 ; \ + or %g1,%lo (ASM_PRIVATE_SYMBOL (cerror)),%g1 ; \ + jmpl %g1+%g0,%g0 ; \ + nop + +#endif /* _SYSCALLASM_H_ */ |