1//===-- runtime/freestanding-tools.h ----------------------------*- 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-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef FORTRAN_RUNTIME_FREESTANDING_TOOLS_H_
10#define FORTRAN_RUNTIME_FREESTANDING_TOOLS_H_
11
12#include "flang/Runtime/api-attrs.h"
13#include "flang/Runtime/c-or-cpp.h"
14#include <algorithm>
15#include <cstring>
16
17// The file defines a set of utilities/classes that might be
18// used to get reduce the dependency on external libraries (e.g. libstdc++).
19
20#if !defined(STD_FILL_N_UNSUPPORTED) && \
21 (defined(__CUDACC__) || defined(__CUDA__)) && defined(__CUDA_ARCH__)
22#define STD_FILL_N_UNSUPPORTED 1
23#endif
24
25#if !defined(STD_MEMMOVE_UNSUPPORTED) && \
26 (defined(__CUDACC__) || defined(__CUDA__)) && defined(__CUDA_ARCH__)
27#define STD_MEMMOVE_UNSUPPORTED 1
28#endif
29
30#if !defined(STD_STRLEN_UNSUPPORTED) && \
31 (defined(__CUDACC__) || defined(__CUDA__)) && defined(__CUDA_ARCH__)
32#define STD_STRLEN_UNSUPPORTED 1
33#endif
34
35#if !defined(STD_MEMCMP_UNSUPPORTED) && \
36 (defined(__CUDACC__) || defined(__CUDA__)) && defined(__CUDA_ARCH__)
37#define STD_MEMCMP_UNSUPPORTED 1
38#endif
39
40#if !defined(STD_REALLOC_UNSUPPORTED) && \
41 (defined(__CUDACC__) || defined(__CUDA__)) && defined(__CUDA_ARCH__)
42#define STD_REALLOC_UNSUPPORTED 1
43#endif
44
45namespace Fortran::runtime {
46
47#if STD_FILL_N_UNSUPPORTED
48// Provides alternative implementation for std::fill_n(), if
49// it is not supported.
50template <typename A>
51static inline RT_API_ATTRS void fill_n(
52 A *start, std::size_t count, const A &value) {
53 for (std::size_t j{0}; j < count; ++j) {
54 start[j] = value;
55 }
56}
57#else // !STD_FILL_N_UNSUPPORTED
58using std::fill_n;
59#endif // !STD_FILL_N_UNSUPPORTED
60
61#if STD_MEMMOVE_UNSUPPORTED
62// Provides alternative implementation for std::memmove(), if
63// it is not supported.
64static inline RT_API_ATTRS void memmove(
65 void *dest, const void *src, std::size_t count) {
66 char *to{reinterpret_cast<char *>(dest)};
67 const char *from{reinterpret_cast<const char *>(src)};
68
69 if (to == from) {
70 return;
71 }
72 if (to + count <= from || from + count <= to) {
73 std::memcpy(dest, src, count);
74 } else if (to < from) {
75 while (count--) {
76 *to++ = *from++;
77 }
78 } else {
79 to += count;
80 from += count;
81 while (count--) {
82 *--to = *--from;
83 }
84 }
85}
86#else // !STD_MEMMOVE_UNSUPPORTED
87using std::memmove;
88#endif // !STD_MEMMOVE_UNSUPPORTED
89
90#if STD_STRLEN_UNSUPPORTED
91// Provides alternative implementation for std::strlen(), if
92// it is not supported.
93static inline RT_API_ATTRS std::size_t strlen(const char *str) {
94 if (!str) {
95 // Return 0 for nullptr.
96 return 0;
97 }
98 const char *end = str;
99 for (; *end != '\0'; ++end)
100 ;
101 return end - str;
102}
103#else // !STD_STRLEN_UNSUPPORTED
104using std::strlen;
105#endif // !STD_STRLEN_UNSUPPORTED
106
107#if STD_MEMCMP_UNSUPPORTED
108// Provides alternative implementation for std::memcmp(), if
109// it is not supported.
110static inline RT_API_ATTRS int memcmp(
111 const void *RESTRICT lhs, const void *RESTRICT rhs, std::size_t count) {
112 auto m1{reinterpret_cast<const unsigned char *>(lhs)};
113 auto m2{reinterpret_cast<const unsigned char *>(rhs)};
114 for (; count--; ++m1, ++m2) {
115 int diff = *m1 - *m2;
116 if (diff != 0) {
117 return diff;
118 }
119 }
120 return 0;
121}
122#else // !STD_MEMCMP_UNSUPPORTED
123using std::memcmp;
124#endif // !STD_MEMCMP_UNSUPPORTED
125
126#if STD_REALLOC_UNSUPPORTED
127static inline RT_API_ATTRS void *realloc(void *ptr, std::size_t newByteSize) {
128 // Return nullptr and let the callers assert that.
129 // TODO: we can provide a straightforward implementation
130 // via malloc/memcpy/free.
131 return nullptr;
132}
133#else // !STD_REALLOC_UNSUPPORTED
134using std::realloc;
135#endif // !STD_REALLOC_UNSUPPORTED
136
137} // namespace Fortran::runtime
138#endif // FORTRAN_RUNTIME_FREESTANDING_TOOLS_H_
139

source code of flang/runtime/freestanding-tools.h