Warning: This file is not a C or C++ file. It does not have highlighting.

1//===-- Implementation using the __builtin_XXX_inline ---------------------===//
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// This file provides generic C++ building blocks to compose memory functions.
10// They rely on the compiler to generate the best possible code through the use
11// of the `__builtin_XXX_inline` builtins. These builtins are currently only
12// available in Clang.
13//
14//===----------------------------------------------------------------------===//
15#ifndef LLVM_LIBC_SRC_STRING_MEMORY_UTILS_OP_BUILTIN_H
16#define LLVM_LIBC_SRC_STRING_MEMORY_UTILS_OP_BUILTIN_H
17
18#include "src/__support/CPP/type_traits.h"
19#include "src/__support/macros/attributes.h" // LIBC_INLINE
20#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL
21#include "src/string/memory_utils/utils.h"
22
23namespace LIBC_NAMESPACE_DECL {
24namespace builtin {
25
26///////////////////////////////////////////////////////////////////////////////
27// Memcpy
28template <size_t Size> struct Memcpy {
29 static constexpr size_t SIZE = Size;
30 LIBC_INLINE static void block_offset(Ptr __restrict dst, CPtr __restrict src,
31 size_t offset) {
32 memcpy_inline<Size>(dst + offset, src + offset);
33 }
34
35 LIBC_INLINE static void block(Ptr __restrict dst, CPtr __restrict src) {
36 block_offset(dst, src, 0);
37 }
38
39 LIBC_INLINE static void tail(Ptr __restrict dst, CPtr __restrict src,
40 size_t count) {
41 block_offset(dst, src, count - SIZE);
42 }
43
44 LIBC_INLINE static void head_tail(Ptr __restrict dst, CPtr __restrict src,
45 size_t count) {
46 block(dst, src);
47 tail(dst, src, count);
48 }
49
50 LIBC_INLINE static void loop_and_tail_offset(Ptr __restrict dst,
51 CPtr __restrict src,
52 size_t count, size_t offset) {
53 static_assert(Size > 1, "a loop of size 1 does not need tail");
54 do {
55 block_offset(dst, src, offset);
56 offset += SIZE;
57 } while (offset < count - SIZE);
58 tail(dst, src, count);
59 }
60
61 LIBC_INLINE static void loop_and_tail(Ptr __restrict dst, CPtr __restrict src,
62 size_t count) {
63 return loop_and_tail_offset(dst, src, count, 0);
64 }
65};
66
67///////////////////////////////////////////////////////////////////////////////
68// Memset
69template <size_t Size> struct Memset {
70 using ME = Memset;
71 static constexpr size_t SIZE = Size;
72 LIBC_INLINE static void block(Ptr dst, uint8_t value) {
73#ifdef LLVM_LIBC_HAS_BUILTIN_MEMSET_INLINE
74 __builtin_memset_inline(dst, value, Size);
75#else
76 static_assert(cpp::always_false<decltype(Size)>,
77 "Missing __builtin_memset_inline");
78 (void)dst;
79 (void)value;
80#endif
81 }
82
83 LIBC_INLINE static void tail(Ptr dst, uint8_t value, size_t count) {
84 block(dst + count - SIZE, value);
85 }
86
87 LIBC_INLINE static void head_tail(Ptr dst, uint8_t value, size_t count) {
88 block(dst, value);
89 tail(dst, value, count);
90 }
91
92 LIBC_INLINE static void loop_and_tail(Ptr dst, uint8_t value, size_t count) {
93 static_assert(Size > 1, "a loop of size 1 does not need tail");
94 size_t offset = 0;
95 do {
96 block(dst + offset, value);
97 offset += SIZE;
98 } while (offset < count - SIZE);
99 tail(dst, value, count);
100 }
101};
102
103///////////////////////////////////////////////////////////////////////////////
104// Bcmp
105template <size_t Size> struct Bcmp {
106 using ME = Bcmp;
107 static constexpr size_t SIZE = Size;
108 LIBC_INLINE static BcmpReturnType block(CPtr, CPtr) {
109 static_assert(cpp::always_false<decltype(Size)>,
110 "Missing __builtin_memcmp_inline");
111 return BcmpReturnType::zero();
112 }
113
114 LIBC_INLINE static BcmpReturnType tail(CPtr, CPtr, size_t) {
115 static_assert(cpp::always_false<decltype(Size)>, "Not implemented");
116 return BcmpReturnType::zero();
117 }
118
119 LIBC_INLINE static BcmpReturnType head_tail(CPtr, CPtr, size_t) {
120 static_assert(cpp::always_false<decltype(Size)>, "Not implemented");
121 return BcmpReturnType::zero();
122 }
123
124 LIBC_INLINE static BcmpReturnType loop_and_tail(CPtr, CPtr, size_t) {
125 static_assert(cpp::always_false<decltype(Size)>, "Not implemented");
126 return BcmpReturnType::zero();
127 }
128};
129
130///////////////////////////////////////////////////////////////////////////////
131// Memcmp
132template <size_t Size> struct Memcmp {
133 using ME = Memcmp;
134 static constexpr size_t SIZE = Size;
135 LIBC_INLINE static MemcmpReturnType block(CPtr, CPtr) {
136 static_assert(cpp::always_false<decltype(Size)>,
137 "Missing __builtin_memcmp_inline");
138 return MemcmpReturnType::zero();
139 }
140
141 LIBC_INLINE static MemcmpReturnType tail(CPtr, CPtr, size_t) {
142 static_assert(cpp::always_false<decltype(Size)>, "Not implemented");
143 return MemcmpReturnType::zero();
144 }
145
146 LIBC_INLINE static MemcmpReturnType head_tail(CPtr, CPtr, size_t) {
147 static_assert(cpp::always_false<decltype(Size)>, "Not implemented");
148 return MemcmpReturnType::zero();
149 }
150
151 LIBC_INLINE static MemcmpReturnType loop_and_tail(CPtr, CPtr, size_t) {
152 static_assert(cpp::always_false<decltype(Size)>, "Not implemented");
153 return MemcmpReturnType::zero();
154 }
155};
156
157} // namespace builtin
158} // namespace LIBC_NAMESPACE_DECL
159
160#endif // LLVM_LIBC_SRC_STRING_MEMORY_UTILS_OP_BUILTIN_H
161

Warning: This file is not a C or C++ file. It does not have highlighting.

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more

source code of libc/src/string/memory_utils/op_builtin.h