ca35ddf0a19862bfabc3aa2d0cf1930d3f091b2b
[org.ibex.core.git] / src / org / xwt / mips / syscalls.c
1 #include <errno.h>
2 #undef errno
3
4 #include <sys/types.h>
5 #include <sys/stat.h>
6
7 // NOTE: This must match up with the Syscalls interface in MIPSInterpreter.java
8 // (in my tree the Syscalls interface is autogenerated from a syscalls.h. We should
9 // do the same)
10 #define SYS_null 0
11 #define SYS_exit 1
12 #define SYS_pause 2
13 #define SYS_open 3
14 #define SYS_close 4
15 #define SYS_read 5
16 #define SYS_write 6
17 #define SYS_sbrk 7
18 #define SYS_fstat 8
19 #define SYS_isatty 9
20 #define SYS_seek 10
21 #define SYS_kill 11
22 #define SYS_getpid 12
23
24 static inline int syscall4(int n, int a, int b, int c, int d) {
25     int ret;
26     __asm__ __volatile__ (
27         ".set noreorder\n\t"
28         "move $2,%1\n\t"
29         "move $4,%2\n\t"
30         "move $5,%3\n\t"
31         "move $6,%4\n\t"
32         "move $7,%5\n\t"
33         "syscall\n\t"
34         "move %0,$2\n\t"
35         ".set reorder\n\t"
36         : "=r"(ret)
37         : "0"(n),"r"(a),"r"(b),"r"(c),"r"(d)
38         : "$2","$4","$5","$6","$7","memory"
39     );
40     return ret;
41 }
42 static inline int syscall0(int n) { return syscall4(n,0,0,0,0); }
43 static inline int syscall1(int n, int a) { return syscall4(n,a,0,0,0); }
44 static inline int syscall2(int n, int a, int b) { return syscall4(n,a,b,0,0); }
45 static inline int syscall3(int n, int a, int b, int c) { return syscall4(n,a,b,c,0); }
46
47 static inline int errnoize(struct _reent *ptr,int n) {
48     if(n < 0) {
49         ptr->_errno = -n;
50         n = -1;
51     }
52     return n;
53 }
54
55 /* These return errno values and must be reentrant */
56 caddr_t _sbrk_r(struct _reent *ptr,int incr) {
57     int n = syscall1(SYS_sbrk,incr);
58     if(n == -ENOMEM) { ptr->_errno = ENOMEM; return (caddr_t)-1; }
59     return (caddr_t) n;
60 }
61
62 int _write_r(struct _reent *ptr,int fd, char *p, int len) { return errnoize(ptr,syscall3(SYS_write,fd,(int)p,len)); }
63 int _read_r(struct _reent *ptr,int fd, char *p, int len) { return errnoize(ptr,syscall3(SYS_read,fd,(int)p,len)); }
64 int _close_r(struct _reent *ptr,int fd) { return errnoize(ptr,syscall1(SYS_close,fd)); }
65 int _fstat_r(struct _reent *ptr,int fd, struct stat *st) { return errnoize(ptr,syscall2(SYS_fstat,fd,(int)st)); }
66 int _lseek_r(struct _reent *ptr,int fd, int off, int whence) { return errnoize(ptr,syscall3(SYS_seek,fd,off,whence)); }
67 int _open_r(struct _reent *ptr,char *name, int flags, int mode) { return errnoize(ptr,syscall3(SYS_open,(int)name,flags,mode)); }
68 int _kill_r(struct _reent *ptr,pid_t pid, int sig) { return errnoize(ptr,syscall2(SYS_kill,(int)pid,sig)); }
69 int _getpid_r(struct _reent *ptr) { return errnoize(ptr,syscall0(SYS_getpid)); }
70
71 /* No errno values */
72 void _exit(int status) {
73     syscall1(SYS_exit,status);
74     for(;;); /* shut up gcc */
75 }
76 int isatty(int fd) { return syscall1(SYS_isatty,fd); }
77
78 void emu_pause() { syscall0(SYS_pause); }