1add_subdirectory(memory_utils)
2
3add_header_library(
4  string_utils
5  HDRS
6    string_utils.h
7  DEPENDS
8    libc.utils.CPP.standalone_cpp
9)
10
11add_entrypoint_object(
12  strcat
13  SRCS
14    strcat.cpp
15  HDRS
16    strcat.h
17  DEPENDS
18    .strcpy
19    .strlen
20    libc.include.string
21)
22
23add_entrypoint_object(
24  strcpy
25  SRCS
26    strcpy.cpp
27  HDRS
28    strcpy.h
29  DEPENDS
30    .memcpy
31    .strlen
32    libc.include.string
33)
34
35add_entrypoint_object(
36  strlen
37  SRCS
38    strlen.cpp
39  HDRS
40    strlen.h
41  DEPENDS
42    libc.include.string
43)
44
45add_entrypoint_object(
46  strcmp
47  SRCS
48    strcmp.cpp
49  HDRS
50    strcmp.h
51  DEPENDS
52    libc.include.string
53)
54
55add_entrypoint_object(
56  memchr
57  SRCS
58    memchr.cpp
59  HDRS
60    memchr.h
61)
62
63add_entrypoint_object(
64  strchr
65  SRCS
66    strchr.cpp
67  HDRS
68    strchr.h
69)
70
71add_entrypoint_object(
72  strstr
73  SRCS
74    strstr.cpp
75  HDRS
76    strstr.h
77)
78
79add_entrypoint_object(
80  strnlen
81  SRCS
82    strnlen.cpp
83  HDRS
84    strnlen.h
85  DEPENDS
86    .memchr
87)
88
89add_entrypoint_object(
90  memrchr
91  SRCS
92    memrchr.cpp
93  HDRS
94    memrchr.h
95)
96
97add_entrypoint_object(
98  strrchr
99  SRCS
100    strrchr.cpp
101  HDRS
102    strrchr.h
103)
104
105add_entrypoint_object(
106  strcspn
107  SRCS
108    strcspn.cpp
109  HDRS
110    strcspn.h
111  DEPENDS
112    .string_utils
113)
114
115add_entrypoint_object(
116  strspn
117  SRCS
118    strspn.cpp
119  HDRS
120    strspn.h
121  DEPENDS
122    libc.utils.CPP.standalone_cpp
123)
124
125add_entrypoint_object(
126  strpbrk
127  SRCS
128    strpbrk.cpp
129  HDRS
130    strpbrk.h
131  DEPENDS
132    .string_utils
133)
134
135add_entrypoint_object(
136  strtok
137  SRCS
138    strtok.cpp
139  HDRS
140    strtok.h
141  DEPENDS
142    .string_utils
143)
144
145add_entrypoint_object(
146  strtok_r
147  SRCS
148    strtok_r.cpp
149  HDRS
150    strtok_r.h
151  DEPENDS
152    .string_utils
153)
154
155# Helper to define a function with multiple implementations
156# - Computes flags to satisfy required/rejected features and arch,
157# - Declares an entry point,
158# - Attach the REQUIRE_CPU_FEATURES property to the target,
159# - Add the fully qualified target to `${name}_implementations` global property for tests.
160function(add_implementation name impl_name)
161  cmake_parse_arguments(
162    "ADD_IMPL"
163    "" # Optional arguments
164    "MARCH" # Single value arguments
165    "REQUIRE;REJECT;SRCS;HDRS;DEPENDS;COMPILE_OPTIONS" # Multi value arguments
166    ${ARGN})
167  compute_flags(flags
168    MARCH ${ADD_IMPL_MARCH}
169    REQUIRE ${ADD_IMPL_REQUIRE}
170    REJECT ${ADD_IMPL_REJECT}
171  )
172  add_entrypoint_object(${impl_name}
173    NAME ${name}
174    SRCS ${ADD_IMPL_SRCS}
175    HDRS ${ADD_IMPL_HDRS}
176    DEPENDS ${ADD_IMPL_DEPENDS}
177    COMPILE_OPTIONS ${ADD_IMPL_COMPILE_OPTIONS} ${flags} -O2
178  )
179  get_fq_target_name(${impl_name} fq_target_name)
180  set_target_properties(${fq_target_name} PROPERTIES REQUIRE_CPU_FEATURES "${ADD_IMPL_REQUIRE}")
181  set_property(GLOBAL APPEND PROPERTY "${name}_implementations" "${fq_target_name}")
182endfunction()
183
184# ------------------------------------------------------------------------------
185# memcpy
186# ------------------------------------------------------------------------------
187
188# include the relevant architecture specific implementations
189if(${LIBC_TARGET_MACHINE} STREQUAL "x86_64")
190  set(LIBC_STRING_TARGET_ARCH "x86")
191  set(MEMCPY_SRC ${LIBC_SOURCE_DIR}/src/string/x86/memcpy.cpp)
192else()
193  set(LIBC_STRING_TARGET_ARCH ${LIBC_TARGET_MACHINE})
194  set(MEMCPY_SRC ${LIBC_SOURCE_DIR}/src/string/memcpy.cpp)
195endif()
196
197function(add_memcpy memcpy_name)
198  add_implementation(memcpy ${memcpy_name}
199    SRCS ${MEMCPY_SRC}
200    HDRS ${LIBC_SOURCE_DIR}/src/string/memcpy.h
201    DEPENDS
202      .memory_utils.memory_utils
203      libc.include.string
204    COMPILE_OPTIONS
205      -fno-builtin-memcpy
206    ${ARGN}
207  )
208endfunction()
209
210if(${LIBC_STRING_TARGET_ARCH} STREQUAL "x86")
211  add_memcpy(memcpy MARCH native)
212else()
213  add_memcpy(memcpy)
214endif()
215
216# ------------------------------------------------------------------------------
217# memset
218# ------------------------------------------------------------------------------
219
220function(add_memset memset_name)
221  add_implementation(memset ${memset_name}
222    SRCS ${LIBC_SOURCE_DIR}/src/string/memset.cpp
223    HDRS ${LIBC_SOURCE_DIR}/src/string/memset.h
224    DEPENDS
225      .memory_utils.memory_utils
226      libc.include.string
227    COMPILE_OPTIONS
228      -fno-builtin-memset
229    ${ARGN}
230  )
231endfunction()
232
233if(${LIBC_STRING_TARGET_ARCH} STREQUAL "x86")
234  add_memset(memset MARCH native)
235else()
236  add_memset(memset)
237endif()
238
239# ------------------------------------------------------------------------------
240# bzero
241# ------------------------------------------------------------------------------
242
243function(add_bzero bzero_name)
244  add_implementation(bzero ${bzero_name}
245    SRCS ${LIBC_SOURCE_DIR}/src/string/bzero.cpp
246    HDRS ${LIBC_SOURCE_DIR}/src/string/bzero.h
247    DEPENDS
248      .memory_utils.memory_utils
249      libc.include.string
250    COMPILE_OPTIONS
251      -fno-builtin-memset
252      -fno-builtin-bzero
253    ${ARGN}
254  )
255endfunction()
256
257if(${LIBC_STRING_TARGET_ARCH} STREQUAL "x86")
258  add_bzero(bzero MARCH native)
259else()
260  add_bzero(bzero)
261endif()
262
263# ------------------------------------------------------------------------------
264# Add all other relevant implementations for the native target.
265# ------------------------------------------------------------------------------
266
267if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_STRING_TARGET_ARCH})
268  include(${LIBC_STRING_TARGET_ARCH}/CMakeLists.txt)
269endif()
270