xref: /linux/tools/include/nolibc/arch-m68k.h (revision 015a99fa76650e7d6efa3e36f20c0f5b346fe9ce)
1 /* SPDX-License-Identifier: LGPL-2.1 OR MIT */
2 /*
3  * m68k specific definitions for NOLIBC
4  * Copyright (C) 2025 Daniel Palmer<daniel@thingy.jp>
5  *
6  * Roughly based on one or more of the other arch files.
7  *
8  */
9 
10 #ifndef _NOLIBC_ARCH_M68K_H
11 #define _NOLIBC_ARCH_M68K_H
12 
13 #include "compiler.h"
14 #include "crt.h"
15 
16 #define _NOLIBC_SYSCALL_CLOBBERLIST "memory"
17 
18 #define my_syscall0(num)                                                      \
19 ({                                                                            \
20 	register long _num __asm__ ("d0") = (num);                            \
21 									      \
22 	__asm__ volatile (                                                    \
23 		"trap #0\n"                                                   \
24 		: "+r"(_num)                                                  \
25 		: "r"(_num)                                                   \
26 		: _NOLIBC_SYSCALL_CLOBBERLIST                                 \
27 	);                                                                    \
28 	_num;                                                                 \
29 })
30 
31 #define my_syscall1(num, arg1)                                                \
32 ({                                                                            \
33 	register long _num __asm__ ("d0") = (num);                            \
34 	register long _arg1 __asm__ ("d1") = (long)(arg1);                    \
35 									      \
36 	__asm__ volatile (                                                    \
37 		"trap #0\n"                                                   \
38 		: "+r"(_num)                                                  \
39 		: "r"(_arg1)                                                  \
40 		: _NOLIBC_SYSCALL_CLOBBERLIST                                 \
41 	);                                                                    \
42 	_num;                                                                 \
43 })
44 
45 #define my_syscall2(num, arg1, arg2)                                          \
46 ({                                                                            \
47 	register long _num __asm__ ("d0") = (num);                            \
48 	register long _arg1 __asm__ ("d1") = (long)(arg1);                    \
49 	register long _arg2 __asm__ ("d2") = (long)(arg2);                    \
50 									      \
51 	__asm__ volatile (                                                    \
52 		"trap #0\n"                                                   \
53 		: "+r"(_num)                                                  \
54 		: "r"(_arg1), "r"(_arg2)                                      \
55 		: _NOLIBC_SYSCALL_CLOBBERLIST                                 \
56 	);                                                                    \
57 	_num;                                                                 \
58 })
59 
60 #define my_syscall3(num, arg1, arg2, arg3)                                    \
61 ({                                                                            \
62 	register long _num __asm__ ("d0")  = (num);                           \
63 	register long _arg1 __asm__ ("d1") = (long)(arg1);                    \
64 	register long _arg2 __asm__ ("d2") = (long)(arg2);                    \
65 	register long _arg3 __asm__ ("d3") = (long)(arg3);                    \
66 									      \
67 	__asm__ volatile (                                                    \
68 		"trap #0\n"                                                   \
69 		: "+r"(_num)                                                  \
70 		: "r"(_arg1), "r"(_arg2), "r"(_arg3)                          \
71 		: _NOLIBC_SYSCALL_CLOBBERLIST                                 \
72 	);                                                                    \
73 	_num;                                                                 \
74 })
75 
76 #define my_syscall4(num, arg1, arg2, arg3, arg4)                              \
77 ({                                                                            \
78 	register long _num __asm__ ("d0") = (num);                            \
79 	register long _arg1 __asm__ ("d1") = (long)(arg1);                    \
80 	register long _arg2 __asm__ ("d2") = (long)(arg2);                    \
81 	register long _arg3 __asm__ ("d3") = (long)(arg3);                    \
82 	register long _arg4 __asm__ ("d4") = (long)(arg4);                    \
83 									      \
84 	__asm__ volatile (                                                    \
85 		"trap #0\n"                                                   \
86 		: "+r" (_num)                                                 \
87 		: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4)              \
88 		: _NOLIBC_SYSCALL_CLOBBERLIST                                 \
89 	);                                                                    \
90 	_num;                                                                 \
91 })
92 
93 #define my_syscall5(num, arg1, arg2, arg3, arg4, arg5)                        \
94 ({                                                                            \
95 	register long _num __asm__ ("d0") = (num);                            \
96 	register long _arg1 __asm__ ("d1") = (long)(arg1);                    \
97 	register long _arg2 __asm__ ("d2") = (long)(arg2);                    \
98 	register long _arg3 __asm__ ("d3") = (long)(arg3);                    \
99 	register long _arg4 __asm__ ("d4") = (long)(arg4);                    \
100 	register long _arg5 __asm__ ("d5") = (long)(arg5);                    \
101 									      \
102 	__asm__ volatile (                                                    \
103 		"trap #0\n"                                                   \
104 		: "+r" (_num)                                                 \
105 		: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5)  \
106 		: _NOLIBC_SYSCALL_CLOBBERLIST                                 \
107 	);                                                                    \
108 	_num;                                                                 \
109 })
110 
111 #define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6)                  \
112 ({                                                                            \
113 	register long _num __asm__ ("d0")  = (num);                           \
114 	register long _arg1 __asm__ ("d1") = (long)(arg1);                    \
115 	register long _arg2 __asm__ ("d2") = (long)(arg2);                    \
116 	register long _arg3 __asm__ ("d3") = (long)(arg3);                    \
117 	register long _arg4 __asm__ ("d4") = (long)(arg4);                    \
118 	register long _arg5 __asm__ ("d5") = (long)(arg5);                    \
119 	register long _arg6 __asm__ ("a0") = (long)(arg6);                    \
120 									      \
121 	__asm__ volatile (                                                    \
122 		"trap #0\n"                                                   \
123 		: "+r" (_num)                                                 \
124 		: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \
125 		  "r"(_arg6)                                                  \
126 		: _NOLIBC_SYSCALL_CLOBBERLIST                                 \
127 	);                                                                    \
128 	_num;                                                                 \
129 })
130 
131 void _start(void);
_start(void)132 void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _start(void)
133 {
134 	__asm__ volatile (
135 		"movel %sp, %sp@-\n"
136 		"jsr _start_c\n"
137 	);
138 	__nolibc_entrypoint_epilogue();
139 }
140 
141 #endif /* _NOLIBC_ARCH_M68K_H */
142