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