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