130 lines · c
1//===--------- inline implementation of arm syscalls --------------* C++ *-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_ARM_SYSCALL_H10#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_ARM_SYSCALL_H11 12#include "src/__support/common.h"13#include "src/__support/macros/config.h"14 15#ifdef __thumb__16#define R7 long r7 = number17#define SYSCALL_INSTR(input_constraint) \18 int temp; \19 LIBC_INLINE_ASM(R"(20 mov %[temp], r721 mov r7, %222 svc #023 mov r7, %[temp]24 )" \25 : "=r"(r0), [temp] "=&r"(temp) \26 : input_constraint \27 : "memory", "cc")28#else29#define R7 register long r7 asm("r7") = number30#define SYSCALL_INSTR(input_constraint) \31 LIBC_INLINE_ASM("svc 0" : "=r"(r0) : input_constraint : "memory", "cc")32#endif33 34#define REGISTER_DECL_0 \35 R7; \36 register long r0 __asm__("r0");37#define REGISTER_DECL_1 \38 R7; \39 register long r0 __asm__("r0") = arg1;40#define REGISTER_DECL_2 \41 REGISTER_DECL_1 \42 register long r1 __asm__("r1") = arg2;43#define REGISTER_DECL_3 \44 REGISTER_DECL_2 \45 register long r2 __asm__("r2") = arg3;46#define REGISTER_DECL_4 \47 REGISTER_DECL_3 \48 register long r3 __asm__("r3") = arg4;49#define REGISTER_DECL_5 \50 REGISTER_DECL_4 \51 register long r4 __asm__("r4") = arg5;52#define REGISTER_DECL_6 \53 REGISTER_DECL_5 \54 register long r5 __asm__("r5") = arg6;55 56#define REGISTER_CONSTRAINT_0 "r"(r7)57#define REGISTER_CONSTRAINT_1 REGISTER_CONSTRAINT_0, "r"(r0)58#define REGISTER_CONSTRAINT_2 REGISTER_CONSTRAINT_1, "r"(r1)59#define REGISTER_CONSTRAINT_3 REGISTER_CONSTRAINT_2, "r"(r2)60#define REGISTER_CONSTRAINT_4 REGISTER_CONSTRAINT_3, "r"(r3)61#define REGISTER_CONSTRAINT_5 REGISTER_CONSTRAINT_4, "r"(r4)62#define REGISTER_CONSTRAINT_6 REGISTER_CONSTRAINT_5, "r"(r5)63 64namespace LIBC_NAMESPACE_DECL {65 66LIBC_INLINE long syscall_impl(long number) {67 REGISTER_DECL_0;68 SYSCALL_INSTR(REGISTER_CONSTRAINT_0);69 return r0;70}71 72LIBC_INLINE long syscall_impl(long number, long arg1) {73 REGISTER_DECL_1;74 SYSCALL_INSTR(REGISTER_CONSTRAINT_1);75 return r0;76}77 78LIBC_INLINE long syscall_impl(long number, long arg1, long arg2) {79 REGISTER_DECL_2;80 SYSCALL_INSTR(REGISTER_CONSTRAINT_2);81 return r0;82}83 84LIBC_INLINE long syscall_impl(long number, long arg1, long arg2, long arg3) {85 REGISTER_DECL_3;86 SYSCALL_INSTR(REGISTER_CONSTRAINT_3);87 return r0;88}89 90LIBC_INLINE long syscall_impl(long number, long arg1, long arg2, long arg3,91 long arg4) {92 REGISTER_DECL_4;93 SYSCALL_INSTR(REGISTER_CONSTRAINT_4);94 return r0;95}96 97LIBC_INLINE long syscall_impl(long number, long arg1, long arg2, long arg3,98 long arg4, long arg5) {99 REGISTER_DECL_5;100 SYSCALL_INSTR(REGISTER_CONSTRAINT_5);101 return r0;102}103 104LIBC_INLINE long syscall_impl(long number, long arg1, long arg2, long arg3,105 long arg4, long arg5, long arg6) {106 REGISTER_DECL_6;107 SYSCALL_INSTR(REGISTER_CONSTRAINT_6);108 return r0;109}110 111} // namespace LIBC_NAMESPACE_DECL112 113#undef REGISTER_DECL_0114#undef REGISTER_DECL_1115#undef REGISTER_DECL_2116#undef REGISTER_DECL_3117#undef REGISTER_DECL_4118#undef REGISTER_DECL_5119#undef REGISTER_DECL_6120 121#undef REGISTER_CONSTRAINT_0122#undef REGISTER_CONSTRAINT_1123#undef REGISTER_CONSTRAINT_2124#undef REGISTER_CONSTRAINT_3125#undef REGISTER_CONSTRAINT_4126#undef REGISTER_CONSTRAINT_5127#undef REGISTER_CONSTRAINT_6128 129#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_ARM_SYSCALL_H130