Linux Audio

Check our new training course

Loading...
v6.8
  1/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
  2/*
  3 * AARCH64 specific definitions for NOLIBC
  4 * Copyright (C) 2017-2022 Willy Tarreau <w@1wt.eu>
  5 */
  6
  7#ifndef _NOLIBC_ARCH_AARCH64_H
  8#define _NOLIBC_ARCH_AARCH64_H
  9
 10#include "compiler.h"
 11#include "crt.h"
 12
 13/* Syscalls for AARCH64 :
 14 *   - registers are 64-bit
 15 *   - stack is 16-byte aligned
 16 *   - syscall number is passed in x8
 17 *   - arguments are in x0, x1, x2, x3, x4, x5
 18 *   - the system call is performed by calling svc 0
 19 *   - syscall return comes in x0.
 20 *   - the arguments are cast to long and assigned into the target registers
 21 *     which are then simply passed as registers to the asm code, so that we
 22 *     don't have to experience issues with register constraints.
 23 */
 24
 25#define my_syscall0(num)                                                      \
 26({                                                                            \
 27	register long _num  __asm__ ("x8") = (num);                           \
 28	register long _arg1 __asm__ ("x0");                                   \
 29									      \
 30	__asm__ volatile (                                                    \
 31		"svc #0\n"                                                    \
 32		: "=r"(_arg1)                                                 \
 33		: "r"(_num)                                                   \
 34		: "memory", "cc"                                              \
 35	);                                                                    \
 36	_arg1;                                                                \
 37})
 38
 39#define my_syscall1(num, arg1)                                                \
 40({                                                                            \
 41	register long _num  __asm__ ("x8") = (num);                           \
 42	register long _arg1 __asm__ ("x0") = (long)(arg1);                    \
 43									      \
 44	__asm__ volatile (                                                    \
 45		"svc #0\n"                                                    \
 46		: "=r"(_arg1)                                                 \
 47		: "r"(_arg1),                                                 \
 48		  "r"(_num)                                                   \
 49		: "memory", "cc"                                              \
 50	);                                                                    \
 51	_arg1;                                                                \
 52})
 53
 54#define my_syscall2(num, arg1, arg2)                                          \
 55({                                                                            \
 56	register long _num  __asm__ ("x8") = (num);                           \
 57	register long _arg1 __asm__ ("x0") = (long)(arg1);                    \
 58	register long _arg2 __asm__ ("x1") = (long)(arg2);                    \
 59									      \
 60	__asm__ volatile (                                                    \
 61		"svc #0\n"                                                    \
 62		: "=r"(_arg1)                                                 \
 63		: "r"(_arg1), "r"(_arg2),                                     \
 64		  "r"(_num)                                                   \
 65		: "memory", "cc"                                              \
 66	);                                                                    \
 67	_arg1;                                                                \
 68})
 69
 70#define my_syscall3(num, arg1, arg2, arg3)                                    \
 71({                                                                            \
 72	register long _num  __asm__ ("x8") = (num);                           \
 73	register long _arg1 __asm__ ("x0") = (long)(arg1);                    \
 74	register long _arg2 __asm__ ("x1") = (long)(arg2);                    \
 75	register long _arg3 __asm__ ("x2") = (long)(arg3);                    \
 76									      \
 77	__asm__ volatile (                                                    \
 78		"svc #0\n"                                                    \
 79		: "=r"(_arg1)                                                 \
 80		: "r"(_arg1), "r"(_arg2), "r"(_arg3),                         \
 81		  "r"(_num)                                                   \
 82		: "memory", "cc"                                              \
 83	);                                                                    \
 84	_arg1;                                                                \
 85})
 86
 87#define my_syscall4(num, arg1, arg2, arg3, arg4)                              \
 88({                                                                            \
 89	register long _num  __asm__ ("x8") = (num);                           \
 90	register long _arg1 __asm__ ("x0") = (long)(arg1);                    \
 91	register long _arg2 __asm__ ("x1") = (long)(arg2);                    \
 92	register long _arg3 __asm__ ("x2") = (long)(arg3);                    \
 93	register long _arg4 __asm__ ("x3") = (long)(arg4);                    \
 94									      \
 95	__asm__ volatile (                                                    \
 96		"svc #0\n"                                                    \
 97		: "=r"(_arg1)                                                 \
 98		: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4),             \
 99		  "r"(_num)                                                   \
100		: "memory", "cc"                                              \
101	);                                                                    \
102	_arg1;                                                                \
103})
104
105#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5)                        \
106({                                                                            \
107	register long _num  __asm__ ("x8") = (num);                           \
108	register long _arg1 __asm__ ("x0") = (long)(arg1);                    \
109	register long _arg2 __asm__ ("x1") = (long)(arg2);                    \
110	register long _arg3 __asm__ ("x2") = (long)(arg3);                    \
111	register long _arg4 __asm__ ("x3") = (long)(arg4);                    \
112	register long _arg5 __asm__ ("x4") = (long)(arg5);                    \
113									      \
114	__asm__ volatile (                                                    \
115		"svc #0\n"                                                    \
116		: "=r" (_arg1)                                                \
117		: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \
118		  "r"(_num)                                                   \
119		: "memory", "cc"                                              \
120	);                                                                    \
121	_arg1;                                                                \
122})
123
124#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6)                  \
125({                                                                            \
126	register long _num  __asm__ ("x8") = (num);                           \
127	register long _arg1 __asm__ ("x0") = (long)(arg1);                    \
128	register long _arg2 __asm__ ("x1") = (long)(arg2);                    \
129	register long _arg3 __asm__ ("x2") = (long)(arg3);                    \
130	register long _arg4 __asm__ ("x3") = (long)(arg4);                    \
131	register long _arg5 __asm__ ("x4") = (long)(arg5);                    \
132	register long _arg6 __asm__ ("x5") = (long)(arg6);                    \
133									      \
134	__asm__ volatile (                                                    \
135		"svc #0\n"                                                    \
136		: "=r" (_arg1)                                                \
137		: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \
138		  "r"(_arg6), "r"(_num)                                       \
139		: "memory", "cc"                                              \
140	);                                                                    \
141	_arg1;                                                                \
142})
143
144/* startup code */
145void __attribute__((weak, noreturn, optimize("Os", "omit-frame-pointer"))) __no_stack_protector _start(void)
146{
147	__asm__ volatile (
148		"mov x0, sp\n"          /* save stack pointer to x0, as arg1 of _start_c */
149		"and sp, x0, -16\n"     /* sp must be 16-byte aligned in the callee      */
150		"bl  _start_c\n"        /* transfer to c runtime                         */
151	);
152	__builtin_unreachable();
153}
154#endif /* _NOLIBC_ARCH_AARCH64_H */
v6.9.4
  1/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
  2/*
  3 * AARCH64 specific definitions for NOLIBC
  4 * Copyright (C) 2017-2022 Willy Tarreau <w@1wt.eu>
  5 */
  6
  7#ifndef _NOLIBC_ARCH_AARCH64_H
  8#define _NOLIBC_ARCH_AARCH64_H
  9
 10#include "compiler.h"
 11#include "crt.h"
 12
 13/* Syscalls for AARCH64 :
 14 *   - registers are 64-bit
 15 *   - stack is 16-byte aligned
 16 *   - syscall number is passed in x8
 17 *   - arguments are in x0, x1, x2, x3, x4, x5
 18 *   - the system call is performed by calling svc 0
 19 *   - syscall return comes in x0.
 20 *   - the arguments are cast to long and assigned into the target registers
 21 *     which are then simply passed as registers to the asm code, so that we
 22 *     don't have to experience issues with register constraints.
 23 */
 24
 25#define my_syscall0(num)                                                      \
 26({                                                                            \
 27	register long _num  __asm__ ("x8") = (num);                           \
 28	register long _arg1 __asm__ ("x0");                                   \
 29									      \
 30	__asm__ volatile (                                                    \
 31		"svc #0\n"                                                    \
 32		: "=r"(_arg1)                                                 \
 33		: "r"(_num)                                                   \
 34		: "memory", "cc"                                              \
 35	);                                                                    \
 36	_arg1;                                                                \
 37})
 38
 39#define my_syscall1(num, arg1)                                                \
 40({                                                                            \
 41	register long _num  __asm__ ("x8") = (num);                           \
 42	register long _arg1 __asm__ ("x0") = (long)(arg1);                    \
 43									      \
 44	__asm__ volatile (                                                    \
 45		"svc #0\n"                                                    \
 46		: "=r"(_arg1)                                                 \
 47		: "r"(_arg1),                                                 \
 48		  "r"(_num)                                                   \
 49		: "memory", "cc"                                              \
 50	);                                                                    \
 51	_arg1;                                                                \
 52})
 53
 54#define my_syscall2(num, arg1, arg2)                                          \
 55({                                                                            \
 56	register long _num  __asm__ ("x8") = (num);                           \
 57	register long _arg1 __asm__ ("x0") = (long)(arg1);                    \
 58	register long _arg2 __asm__ ("x1") = (long)(arg2);                    \
 59									      \
 60	__asm__ volatile (                                                    \
 61		"svc #0\n"                                                    \
 62		: "=r"(_arg1)                                                 \
 63		: "r"(_arg1), "r"(_arg2),                                     \
 64		  "r"(_num)                                                   \
 65		: "memory", "cc"                                              \
 66	);                                                                    \
 67	_arg1;                                                                \
 68})
 69
 70#define my_syscall3(num, arg1, arg2, arg3)                                    \
 71({                                                                            \
 72	register long _num  __asm__ ("x8") = (num);                           \
 73	register long _arg1 __asm__ ("x0") = (long)(arg1);                    \
 74	register long _arg2 __asm__ ("x1") = (long)(arg2);                    \
 75	register long _arg3 __asm__ ("x2") = (long)(arg3);                    \
 76									      \
 77	__asm__ volatile (                                                    \
 78		"svc #0\n"                                                    \
 79		: "=r"(_arg1)                                                 \
 80		: "r"(_arg1), "r"(_arg2), "r"(_arg3),                         \
 81		  "r"(_num)                                                   \
 82		: "memory", "cc"                                              \
 83	);                                                                    \
 84	_arg1;                                                                \
 85})
 86
 87#define my_syscall4(num, arg1, arg2, arg3, arg4)                              \
 88({                                                                            \
 89	register long _num  __asm__ ("x8") = (num);                           \
 90	register long _arg1 __asm__ ("x0") = (long)(arg1);                    \
 91	register long _arg2 __asm__ ("x1") = (long)(arg2);                    \
 92	register long _arg3 __asm__ ("x2") = (long)(arg3);                    \
 93	register long _arg4 __asm__ ("x3") = (long)(arg4);                    \
 94									      \
 95	__asm__ volatile (                                                    \
 96		"svc #0\n"                                                    \
 97		: "=r"(_arg1)                                                 \
 98		: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4),             \
 99		  "r"(_num)                                                   \
100		: "memory", "cc"                                              \
101	);                                                                    \
102	_arg1;                                                                \
103})
104
105#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5)                        \
106({                                                                            \
107	register long _num  __asm__ ("x8") = (num);                           \
108	register long _arg1 __asm__ ("x0") = (long)(arg1);                    \
109	register long _arg2 __asm__ ("x1") = (long)(arg2);                    \
110	register long _arg3 __asm__ ("x2") = (long)(arg3);                    \
111	register long _arg4 __asm__ ("x3") = (long)(arg4);                    \
112	register long _arg5 __asm__ ("x4") = (long)(arg5);                    \
113									      \
114	__asm__ volatile (                                                    \
115		"svc #0\n"                                                    \
116		: "=r" (_arg1)                                                \
117		: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \
118		  "r"(_num)                                                   \
119		: "memory", "cc"                                              \
120	);                                                                    \
121	_arg1;                                                                \
122})
123
124#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6)                  \
125({                                                                            \
126	register long _num  __asm__ ("x8") = (num);                           \
127	register long _arg1 __asm__ ("x0") = (long)(arg1);                    \
128	register long _arg2 __asm__ ("x1") = (long)(arg2);                    \
129	register long _arg3 __asm__ ("x2") = (long)(arg3);                    \
130	register long _arg4 __asm__ ("x3") = (long)(arg4);                    \
131	register long _arg5 __asm__ ("x4") = (long)(arg5);                    \
132	register long _arg6 __asm__ ("x5") = (long)(arg6);                    \
133									      \
134	__asm__ volatile (                                                    \
135		"svc #0\n"                                                    \
136		: "=r" (_arg1)                                                \
137		: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \
138		  "r"(_arg6), "r"(_num)                                       \
139		: "memory", "cc"                                              \
140	);                                                                    \
141	_arg1;                                                                \
142})
143
144/* startup code */
145void __attribute__((weak, noreturn, optimize("Os", "omit-frame-pointer"))) __no_stack_protector _start(void)
146{
147	__asm__ volatile (
148		"mov x0, sp\n"          /* save stack pointer to x0, as arg1 of _start_c */
149		"and sp, x0, -16\n"     /* sp must be 16-byte aligned in the callee      */
150		"bl  _start_c\n"        /* transfer to c runtime                         */
151	);
152	__builtin_unreachable();
153}
154#endif /* _NOLIBC_ARCH_AARCH64_H */