Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/tools/include/nolibc/arch-sh.h
26292 views
1
/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
2
/*
3
* SuperH specific definitions for NOLIBC
4
* Copyright (C) 2025 Thomas Weißschuh <[email protected]>
5
*/
6
7
#ifndef _NOLIBC_ARCH_SH_H
8
#define _NOLIBC_ARCH_SH_H
9
10
#include "compiler.h"
11
#include "crt.h"
12
13
/*
14
* Syscalls for SuperH:
15
* - registers are 32bit wide
16
* - syscall number is passed in r3
17
* - arguments are in r4, r5, r6, r7, r0, r1, r2
18
* - the system call is performed by calling trapa #31
19
* - syscall return value is in r0
20
*/
21
22
#define my_syscall0(num) \
23
({ \
24
register long _num __asm__ ("r3") = (num); \
25
register long _ret __asm__ ("r0"); \
26
\
27
__asm__ volatile ( \
28
"trapa #31" \
29
: "=r"(_ret) \
30
: "r"(_num) \
31
: "memory", "cc" \
32
); \
33
_ret; \
34
})
35
36
#define my_syscall1(num, arg1) \
37
({ \
38
register long _num __asm__ ("r3") = (num); \
39
register long _ret __asm__ ("r0"); \
40
register long _arg1 __asm__ ("r4") = (long)(arg1); \
41
\
42
__asm__ volatile ( \
43
"trapa #31" \
44
: "=r"(_ret) \
45
: "r"(_num), "r"(_arg1) \
46
: "memory", "cc" \
47
); \
48
_ret; \
49
})
50
51
#define my_syscall2(num, arg1, arg2) \
52
({ \
53
register long _num __asm__ ("r3") = (num); \
54
register long _ret __asm__ ("r0"); \
55
register long _arg1 __asm__ ("r4") = (long)(arg1); \
56
register long _arg2 __asm__ ("r5") = (long)(arg2); \
57
\
58
__asm__ volatile ( \
59
"trapa #31" \
60
: "=r"(_ret) \
61
: "r"(_num), "r"(_arg1), "r"(_arg2) \
62
: "memory", "cc" \
63
); \
64
_ret; \
65
})
66
67
#define my_syscall3(num, arg1, arg2, arg3) \
68
({ \
69
register long _num __asm__ ("r3") = (num); \
70
register long _ret __asm__ ("r0"); \
71
register long _arg1 __asm__ ("r4") = (long)(arg1); \
72
register long _arg2 __asm__ ("r5") = (long)(arg2); \
73
register long _arg3 __asm__ ("r6") = (long)(arg3); \
74
\
75
__asm__ volatile ( \
76
"trapa #31" \
77
: "=r"(_ret) \
78
: "r"(_num), "r"(_arg1), "r"(_arg2), "r"(_arg3) \
79
: "memory", "cc" \
80
); \
81
_ret; \
82
})
83
84
#define my_syscall4(num, arg1, arg2, arg3, arg4) \
85
({ \
86
register long _num __asm__ ("r3") = (num); \
87
register long _ret __asm__ ("r0"); \
88
register long _arg1 __asm__ ("r4") = (long)(arg1); \
89
register long _arg2 __asm__ ("r5") = (long)(arg2); \
90
register long _arg3 __asm__ ("r6") = (long)(arg3); \
91
register long _arg4 __asm__ ("r7") = (long)(arg4); \
92
\
93
__asm__ volatile ( \
94
"trapa #31" \
95
: "=r"(_ret) \
96
: "r"(_num), "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4) \
97
: "memory", "cc" \
98
); \
99
_ret; \
100
})
101
102
#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5) \
103
({ \
104
register long _num __asm__ ("r3") = (num); \
105
register long _ret __asm__ ("r0"); \
106
register long _arg1 __asm__ ("r4") = (long)(arg1); \
107
register long _arg2 __asm__ ("r5") = (long)(arg2); \
108
register long _arg3 __asm__ ("r6") = (long)(arg3); \
109
register long _arg4 __asm__ ("r7") = (long)(arg4); \
110
register long _arg5 __asm__ ("r0") = (long)(arg5); \
111
\
112
__asm__ volatile ( \
113
"trapa #31" \
114
: "=r"(_ret) \
115
: "r"(_num), "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), \
116
"r"(_arg5) \
117
: "memory", "cc" \
118
); \
119
_ret; \
120
})
121
122
#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \
123
({ \
124
register long _num __asm__ ("r3") = (num); \
125
register long _ret __asm__ ("r0"); \
126
register long _arg1 __asm__ ("r4") = (long)(arg1); \
127
register long _arg2 __asm__ ("r5") = (long)(arg2); \
128
register long _arg3 __asm__ ("r6") = (long)(arg3); \
129
register long _arg4 __asm__ ("r7") = (long)(arg4); \
130
register long _arg5 __asm__ ("r0") = (long)(arg5); \
131
register long _arg6 __asm__ ("r1") = (long)(arg6); \
132
\
133
__asm__ volatile ( \
134
"trapa #31" \
135
: "=r"(_ret) \
136
: "r"(_num), "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), \
137
"r"(_arg5), "r"(_arg6) \
138
: "memory", "cc" \
139
); \
140
_ret; \
141
})
142
143
/* startup code */
144
void _start_wrapper(void);
145
void __attribute__((weak,noreturn)) __nolibc_entrypoint __no_stack_protector _start_wrapper(void)
146
{
147
__asm__ volatile (
148
".global _start\n" /* The C function will have a prologue, */
149
".type _start, @function\n" /* corrupting "sp" */
150
".weak _start\n"
151
"_start:\n"
152
153
"mov sp, r4\n" /* save argc pointer to r4, as arg1 of _start_c */
154
"bsr _start_c\n" /* transfer to c runtime */
155
"nop\n" /* delay slot */
156
157
".size _start, .-_start\n"
158
);
159
__nolibc_entrypoint_epilogue();
160
}
161
162
#endif /* _NOLIBC_ARCH_SH_H */
163
164