xref: /openbmc/qemu/tests/tcg/mips/hello-mips.c (revision 106ea2db123ff4ed57b38b4c0084b46833a3ae4c)
1*106ea2dbSAlex Bennée /*
2*106ea2dbSAlex Bennée * MIPS o32 Linux syscall example
3*106ea2dbSAlex Bennée *
4*106ea2dbSAlex Bennée * http://www.linux-mips.org/wiki/RISC/os
5*106ea2dbSAlex Bennée * http://www.linux-mips.org/wiki/MIPSABIHistory
6*106ea2dbSAlex Bennée * http://www.linux.com/howtos/Assembly-HOWTO/mips.shtml
7*106ea2dbSAlex Bennée *
8*106ea2dbSAlex Bennée * mipsel-linux-gcc -nostdlib -mno-abicalls -fno-PIC -mabi=32 \
9*106ea2dbSAlex Bennée *                  -O2 -static -o hello-mips hello-mips.c
10*106ea2dbSAlex Bennée *
11*106ea2dbSAlex Bennée */
12*106ea2dbSAlex Bennée #define __NR_SYSCALL_BASE	4000
13*106ea2dbSAlex Bennée #define __NR_exit			(__NR_SYSCALL_BASE+  1)
14*106ea2dbSAlex Bennée #define __NR_write			(__NR_SYSCALL_BASE+  4)
15*106ea2dbSAlex Bennée 
16*106ea2dbSAlex Bennée static inline void exit1(int status)
17*106ea2dbSAlex Bennée {
18*106ea2dbSAlex Bennée     register unsigned long __a0 asm("$4") = (unsigned long) status;
19*106ea2dbSAlex Bennée 
20*106ea2dbSAlex Bennée     __asm__ __volatile__ (
21*106ea2dbSAlex Bennée         "	.set push	\n"
22*106ea2dbSAlex Bennée         "	.set noreorder	\n"
23*106ea2dbSAlex Bennée         "	li	$2, %0	\n"
24*106ea2dbSAlex Bennée         "	syscall		\n"
25*106ea2dbSAlex Bennée         "	.set pop	"
26*106ea2dbSAlex Bennée         :
27*106ea2dbSAlex Bennée 	: "i" (__NR_exit), "r" (__a0)
28*106ea2dbSAlex Bennée 	: "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24",
29*106ea2dbSAlex Bennée 	  "memory");
30*106ea2dbSAlex Bennée }
31*106ea2dbSAlex Bennée 
32*106ea2dbSAlex Bennée static inline int write(int fd, const char *buf, int len)
33*106ea2dbSAlex Bennée {
34*106ea2dbSAlex Bennée     register unsigned long __a0 asm("$4") = (unsigned long) fd;
35*106ea2dbSAlex Bennée     register unsigned long __a1 asm("$5") = (unsigned long) buf;
36*106ea2dbSAlex Bennée     register unsigned long __a2 asm("$6") = (unsigned long) len;
37*106ea2dbSAlex Bennée     register unsigned long __a3 asm("$7");
38*106ea2dbSAlex Bennée     unsigned long __v0;
39*106ea2dbSAlex Bennée 
40*106ea2dbSAlex Bennée     __asm__ __volatile__ (
41*106ea2dbSAlex Bennée         "	.set push	\n"
42*106ea2dbSAlex Bennée         "	.set noreorder	\n"
43*106ea2dbSAlex Bennée         "	li	$2, %2	\n"
44*106ea2dbSAlex Bennée         "	syscall		\n"
45*106ea2dbSAlex Bennée         "	move	%0, $2	\n"
46*106ea2dbSAlex Bennée         "	.set pop	"
47*106ea2dbSAlex Bennée         : "=r" (__v0), "=r" (__a3)
48*106ea2dbSAlex Bennée         : "i" (__NR_write), "r" (__a0), "r" (__a1), "r" (__a2)
49*106ea2dbSAlex Bennée 	: "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24",
50*106ea2dbSAlex Bennée 	  "memory");
51*106ea2dbSAlex Bennée 
52*106ea2dbSAlex Bennée /*    if (__a3 == 0) */
53*106ea2dbSAlex Bennée         return (int) __v0;
54*106ea2dbSAlex Bennée /*
55*106ea2dbSAlex Bennée     errno = __v0;
56*106ea2dbSAlex Bennée     return -1;
57*106ea2dbSAlex Bennée  */
58*106ea2dbSAlex Bennée }
59*106ea2dbSAlex Bennée 
60*106ea2dbSAlex Bennée void __start(void)
61*106ea2dbSAlex Bennée {
62*106ea2dbSAlex Bennée     write (1, "Hello, World!\n", 14);
63*106ea2dbSAlex Bennée     exit1 (42);
64*106ea2dbSAlex Bennée }
65