xref: /linux/tools/include/nolibc/arch-hexagon.h (revision 542fed2ef2ff7e580cc25efb174f5e1237e3b0eb)
13842a1f4SThomas Weißschuh /* SPDX-License-Identifier: LGPL-2.1 OR MIT */
23842a1f4SThomas Weißschuh /*
33842a1f4SThomas Weißschuh  * hexagon specific definitions for NOLIBC
43842a1f4SThomas Weißschuh  * Copyright (C) 2026 Thomas Weißschuh <linux@weissschuh.net>
53842a1f4SThomas Weißschuh  */
63842a1f4SThomas Weißschuh 
73842a1f4SThomas Weißschuh #ifndef _NOLIBC_ARCH_HEXAGON_H
83842a1f4SThomas Weißschuh #define _NOLIBC_ARCH_HEXAGON_H
93842a1f4SThomas Weißschuh 
103842a1f4SThomas Weißschuh #include <linux/unistd.h>
113842a1f4SThomas Weißschuh 
123842a1f4SThomas Weißschuh #include "compiler.h"
133842a1f4SThomas Weißschuh #include "crt.h"
143842a1f4SThomas Weißschuh 
153842a1f4SThomas Weißschuh /*
163842a1f4SThomas Weißschuh  * Syscalls for hexagon:
173842a1f4SThomas Weißschuh  *   - syscall number is passed in r6
183842a1f4SThomas Weißschuh  *   - arguments are in r0, r1, r2, r3, r4, r5
193842a1f4SThomas Weißschuh  *   - the system call is performed by calling trap0(#1)
203842a1f4SThomas Weißschuh  *   - syscall return value is in r0
213842a1f4SThomas Weißschuh  */
223842a1f4SThomas Weißschuh 
233842a1f4SThomas Weißschuh #define _NOLIBC_SYSCALL_CLOBBERLIST "memory"
243842a1f4SThomas Weißschuh 
253842a1f4SThomas Weißschuh #define __nolibc_syscall0(num)                                                \
263842a1f4SThomas Weißschuh ({                                                                            \
273842a1f4SThomas Weißschuh 	register long _num __asm__ ("r6") = (num);                            \
283842a1f4SThomas Weißschuh 	register long _arg1 __asm__ ("r0");                                   \
293842a1f4SThomas Weißschuh 									      \
303842a1f4SThomas Weißschuh 	__asm__ volatile (                                                    \
313842a1f4SThomas Weißschuh 		"trap0(#1)\n"                                                 \
323842a1f4SThomas Weißschuh 		: "=r"(_arg1)                                                 \
333842a1f4SThomas Weißschuh 		: "r"(_num)                                                   \
343842a1f4SThomas Weißschuh 		: _NOLIBC_SYSCALL_CLOBBERLIST                                 \
353842a1f4SThomas Weißschuh 	);                                                                    \
363842a1f4SThomas Weißschuh 	_arg1;                                                                \
373842a1f4SThomas Weißschuh })
383842a1f4SThomas Weißschuh 
393842a1f4SThomas Weißschuh #define __nolibc_syscall1(num, arg1)                                          \
403842a1f4SThomas Weißschuh ({                                                                            \
413842a1f4SThomas Weißschuh 	register long _num __asm__ ("r6") = (num);                            \
423842a1f4SThomas Weißschuh 	register long _arg1 __asm__ ("r0") = (long)(arg1);                    \
433842a1f4SThomas Weißschuh 									      \
443842a1f4SThomas Weißschuh 	__asm__ volatile (                                                    \
453842a1f4SThomas Weißschuh 		"trap0(#1)\n"                                                 \
463842a1f4SThomas Weißschuh 		: "+r"(_arg1)                                                 \
473842a1f4SThomas Weißschuh 		: "r"(_num)                                                   \
483842a1f4SThomas Weißschuh 		: _NOLIBC_SYSCALL_CLOBBERLIST                                 \
493842a1f4SThomas Weißschuh 	);                                                                    \
503842a1f4SThomas Weißschuh 	_arg1;                                                                \
513842a1f4SThomas Weißschuh })
523842a1f4SThomas Weißschuh 
533842a1f4SThomas Weißschuh #define __nolibc_syscall2(num, arg1, arg2)                                    \
543842a1f4SThomas Weißschuh ({                                                                            \
553842a1f4SThomas Weißschuh 	register long _num __asm__ ("r6") = (num);                            \
563842a1f4SThomas Weißschuh 	register long _arg1 __asm__ ("r0") = (long)(arg1);                    \
573842a1f4SThomas Weißschuh 	register long _arg2 __asm__ ("r1") = (long)(arg2);                    \
583842a1f4SThomas Weißschuh 									      \
593842a1f4SThomas Weißschuh 	__asm__ volatile (                                                    \
603842a1f4SThomas Weißschuh 		"trap0(#1)\n"                                                 \
613842a1f4SThomas Weißschuh 		: "+r"(_arg1)                                                 \
623842a1f4SThomas Weißschuh 		: "r"(_arg2),                                                 \
633842a1f4SThomas Weißschuh 		  "r"(_num)                                                   \
643842a1f4SThomas Weißschuh 		: _NOLIBC_SYSCALL_CLOBBERLIST                                 \
653842a1f4SThomas Weißschuh 	);                                                                    \
663842a1f4SThomas Weißschuh 	_arg1;                                                                \
673842a1f4SThomas Weißschuh })
683842a1f4SThomas Weißschuh 
693842a1f4SThomas Weißschuh #define __nolibc_syscall3(num, arg1, arg2, arg3)                              \
703842a1f4SThomas Weißschuh ({                                                                            \
713842a1f4SThomas Weißschuh 	register long _num __asm__ ("r6") = (num);                            \
723842a1f4SThomas Weißschuh 	register long _arg1 __asm__ ("r0") = (long)(arg1);                    \
733842a1f4SThomas Weißschuh 	register long _arg2 __asm__ ("r1") = (long)(arg2);                    \
743842a1f4SThomas Weißschuh 	register long _arg3 __asm__ ("r2") = (long)(arg3);                    \
753842a1f4SThomas Weißschuh 									      \
763842a1f4SThomas Weißschuh 	__asm__ volatile (                                                    \
773842a1f4SThomas Weißschuh 		"trap0(#1)\n"                                                 \
783842a1f4SThomas Weißschuh 		: "+r"(_arg1)                                                 \
793842a1f4SThomas Weißschuh 		: "r"(_arg2), "r"(_arg3),                                     \
803842a1f4SThomas Weißschuh 		  "r"(_num)                                                   \
813842a1f4SThomas Weißschuh 		: _NOLIBC_SYSCALL_CLOBBERLIST                                 \
823842a1f4SThomas Weißschuh 	);                                                                    \
833842a1f4SThomas Weißschuh 	_arg1;                                                                \
843842a1f4SThomas Weißschuh })
853842a1f4SThomas Weißschuh 
863842a1f4SThomas Weißschuh #define __nolibc_syscall4(num, arg1, arg2, arg3, arg4)                        \
873842a1f4SThomas Weißschuh ({                                                                            \
883842a1f4SThomas Weißschuh 	register long _num __asm__ ("r6") = (num);                            \
893842a1f4SThomas Weißschuh 	register long _arg1 __asm__ ("r0") = (long)(arg1);                    \
903842a1f4SThomas Weißschuh 	register long _arg2 __asm__ ("r1") = (long)(arg2);                    \
913842a1f4SThomas Weißschuh 	register long _arg3 __asm__ ("r2") = (long)(arg3);                    \
923842a1f4SThomas Weißschuh 	register long _arg4 __asm__ ("r3") = (long)(arg4);                    \
933842a1f4SThomas Weißschuh 									      \
943842a1f4SThomas Weißschuh 	__asm__ volatile (                                                    \
953842a1f4SThomas Weißschuh 		"trap0(#1)\n"                                                 \
963842a1f4SThomas Weißschuh 		: "+r"(_arg1)                                                 \
973842a1f4SThomas Weißschuh 		: "r"(_arg2), "r"(_arg3), "r"(_arg4),                         \
983842a1f4SThomas Weißschuh 		  "r"(_num)                                                   \
993842a1f4SThomas Weißschuh 		: _NOLIBC_SYSCALL_CLOBBERLIST                                 \
1003842a1f4SThomas Weißschuh 	);                                                                    \
1013842a1f4SThomas Weißschuh 	_arg1;                                                                \
1023842a1f4SThomas Weißschuh })
1033842a1f4SThomas Weißschuh 
1043842a1f4SThomas Weißschuh #define __nolibc_syscall5(num, arg1, arg2, arg3, arg4, arg5)                  \
1053842a1f4SThomas Weißschuh ({                                                                            \
1063842a1f4SThomas Weißschuh 	register long _num __asm__ ("r6") = (num);                            \
1073842a1f4SThomas Weißschuh 	register long _arg1 __asm__ ("r0") = (long)(arg1);                    \
1083842a1f4SThomas Weißschuh 	register long _arg2 __asm__ ("r1") = (long)(arg2);                    \
1093842a1f4SThomas Weißschuh 	register long _arg3 __asm__ ("r2") = (long)(arg3);                    \
1103842a1f4SThomas Weißschuh 	register long _arg4 __asm__ ("r3") = (long)(arg4);                    \
1113842a1f4SThomas Weißschuh 	register long _arg5 __asm__ ("r4") = (long)(arg5);                    \
1123842a1f4SThomas Weißschuh 									      \
1133842a1f4SThomas Weißschuh 	__asm__ volatile (                                                    \
1143842a1f4SThomas Weißschuh 		"trap0(#1)\n"                                                 \
1153842a1f4SThomas Weißschuh 		: "+r"(_arg1)                                                 \
1163842a1f4SThomas Weißschuh 		: "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5),             \
1173842a1f4SThomas Weißschuh 		  "r"(_num)                                                   \
1183842a1f4SThomas Weißschuh 		: _NOLIBC_SYSCALL_CLOBBERLIST                                 \
1193842a1f4SThomas Weißschuh 	);                                                                    \
1203842a1f4SThomas Weißschuh 	_arg1;                                                                \
1213842a1f4SThomas Weißschuh })
1223842a1f4SThomas Weißschuh 
1233842a1f4SThomas Weißschuh #define __nolibc_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6)            \
1243842a1f4SThomas Weißschuh ({                                                                            \
1253842a1f4SThomas Weißschuh 	register long _num __asm__ ("r6") = (num);                            \
1263842a1f4SThomas Weißschuh 	register long _arg1 __asm__ ("r0") = (long)(arg1);                    \
1273842a1f4SThomas Weißschuh 	register long _arg2 __asm__ ("r1") = (long)(arg2);                    \
1283842a1f4SThomas Weißschuh 	register long _arg3 __asm__ ("r2") = (long)(arg3);                    \
1293842a1f4SThomas Weißschuh 	register long _arg4 __asm__ ("r3") = (long)(arg4);                    \
1303842a1f4SThomas Weißschuh 	register long _arg5 __asm__ ("r4") = (long)(arg5);                    \
1313842a1f4SThomas Weißschuh 	register long _arg6 __asm__ ("r5") = (long)(arg6);                    \
1323842a1f4SThomas Weißschuh 									      \
1333842a1f4SThomas Weißschuh 	__asm__ volatile (                                                    \
1343842a1f4SThomas Weißschuh 		"trap0(#1)\n"                                                 \
1353842a1f4SThomas Weißschuh 		: "+r"(_arg1)                                                 \
1363842a1f4SThomas Weißschuh 		: "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), "r"(_arg6), \
1373842a1f4SThomas Weißschuh 		  "r"(_num)                                                   \
1383842a1f4SThomas Weißschuh 		: _NOLIBC_SYSCALL_CLOBBERLIST                                 \
1393842a1f4SThomas Weißschuh 	);                                                                    \
1403842a1f4SThomas Weißschuh 	_arg1;                                                                \
1413842a1f4SThomas Weißschuh })
1423842a1f4SThomas Weißschuh 
1433842a1f4SThomas Weißschuh #ifndef NOLIBC_NO_RUNTIME
1443842a1f4SThomas Weißschuh /* startup code */
1453842a1f4SThomas Weißschuh void __attribute__((weak, noreturn))
1463842a1f4SThomas Weißschuh __nolibc_entrypoint __nolibc_no_stack_protector
_start(void)1473842a1f4SThomas Weißschuh _start(void)
1483842a1f4SThomas Weißschuh {
1493842a1f4SThomas Weißschuh 	__asm__ volatile (
1503842a1f4SThomas Weißschuh 		"r0 = sp\n"                 /* save stack pointer to r0, as arg1 of _start_c */
1513842a1f4SThomas Weißschuh 		"call _start_c\n"           /* transfer to c runtime                        */
1523842a1f4SThomas Weißschuh 	);
1533842a1f4SThomas Weißschuh 	__nolibc_entrypoint_epilogue();
1543842a1f4SThomas Weißschuh }
1553842a1f4SThomas Weißschuh #endif /* NOLIBC_NO_RUNTIME */
1563842a1f4SThomas Weißschuh 
157*74136192SThomas Weißschuh #define __NOLIBC_PAD_64BIT_SYSCALL_ARGUMENT_PAIR
1583842a1f4SThomas Weißschuh 
1593842a1f4SThomas Weißschuh #endif /* _NOLIBC_ARCH_HEXAGON_H */
160