1106ea2dbSAlex Bennée /*
2106ea2dbSAlex Bennée * MIPS o32 Linux syscall example
3106ea2dbSAlex Bennée *
4106ea2dbSAlex Bennée * http://www.linux-mips.org/wiki/RISC/os
5106ea2dbSAlex Bennée * http://www.linux-mips.org/wiki/MIPSABIHistory
6106ea2dbSAlex Bennée * http://www.linux.com/howtos/Assembly-HOWTO/mips.shtml
7106ea2dbSAlex Bennée *
8*580731dcSAkihiko Odaki * mipsel-linux-gcc -nostdlib -mno-abicalls -fno-PIC -fno-stack-protector \
9*580731dcSAkihiko Odaki * -mabi=32 -O2 -static -o hello-mips hello-mips.c
10106ea2dbSAlex Bennée *
11106ea2dbSAlex Bennée */
12106ea2dbSAlex Bennée #define __NR_SYSCALL_BASE 4000
13106ea2dbSAlex Bennée #define __NR_exit (__NR_SYSCALL_BASE+ 1)
14106ea2dbSAlex Bennée #define __NR_write (__NR_SYSCALL_BASE+ 4)
15106ea2dbSAlex Bennée
exit1(int status)16106ea2dbSAlex Bennée static inline void exit1(int status)
17106ea2dbSAlex Bennée {
18106ea2dbSAlex Bennée register unsigned long __a0 asm("$4") = (unsigned long) status;
19106ea2dbSAlex Bennée
20106ea2dbSAlex Bennée __asm__ __volatile__ (
21106ea2dbSAlex Bennée " .set push \n"
22106ea2dbSAlex Bennée " .set noreorder \n"
23106ea2dbSAlex Bennée " li $2, %0 \n"
24106ea2dbSAlex Bennée " syscall \n"
25106ea2dbSAlex Bennée " .set pop "
26106ea2dbSAlex Bennée :
27106ea2dbSAlex Bennée : "i" (__NR_exit), "r" (__a0)
28106ea2dbSAlex Bennée : "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24",
29106ea2dbSAlex Bennée "memory");
30106ea2dbSAlex Bennée }
31106ea2dbSAlex Bennée
write(int fd,const char * buf,int len)32106ea2dbSAlex Bennée static inline int write(int fd, const char *buf, int len)
33106ea2dbSAlex Bennée {
34106ea2dbSAlex Bennée register unsigned long __a0 asm("$4") = (unsigned long) fd;
35106ea2dbSAlex Bennée register unsigned long __a1 asm("$5") = (unsigned long) buf;
36106ea2dbSAlex Bennée register unsigned long __a2 asm("$6") = (unsigned long) len;
37106ea2dbSAlex Bennée register unsigned long __a3 asm("$7");
38106ea2dbSAlex Bennée unsigned long __v0;
39106ea2dbSAlex Bennée
40106ea2dbSAlex Bennée __asm__ __volatile__ (
41106ea2dbSAlex Bennée " .set push \n"
42106ea2dbSAlex Bennée " .set noreorder \n"
43106ea2dbSAlex Bennée " li $2, %2 \n"
44106ea2dbSAlex Bennée " syscall \n"
45106ea2dbSAlex Bennée " move %0, $2 \n"
46106ea2dbSAlex Bennée " .set pop "
47106ea2dbSAlex Bennée : "=r" (__v0), "=r" (__a3)
48106ea2dbSAlex Bennée : "i" (__NR_write), "r" (__a0), "r" (__a1), "r" (__a2)
49106ea2dbSAlex Bennée : "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24",
50106ea2dbSAlex Bennée "memory");
51106ea2dbSAlex Bennée
52106ea2dbSAlex Bennée /* if (__a3 == 0) */
53106ea2dbSAlex Bennée return (int) __v0;
54106ea2dbSAlex Bennée /*
55106ea2dbSAlex Bennée errno = __v0;
56106ea2dbSAlex Bennée return -1;
57106ea2dbSAlex Bennée */
58106ea2dbSAlex Bennée }
59106ea2dbSAlex Bennée
__start(void)60106ea2dbSAlex Bennée void __start(void)
61106ea2dbSAlex Bennée {
62106ea2dbSAlex Bennée write (1, "Hello, World!\n", 14);
63b4f39615SAlex Bennée exit1(0);
64106ea2dbSAlex Bennée }
65