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 memccpy 13 SRCS 14 memccpy.cpp 15 HDRS 16 memccpy.h 17) 18 19 20add_entrypoint_object( 21 mempcpy 22 SRCS 23 mempcpy.cpp 24 HDRS 25 mempcpy.h 26 DEPENDS 27 libc.src.string.memcpy 28) 29 30add_entrypoint_object( 31 memchr 32 SRCS 33 memchr.cpp 34 HDRS 35 memchr.h 36 DEPENDS 37 .string_utils 38) 39 40add_entrypoint_object( 41 memmove 42 SRCS 43 memmove.cpp 44 HDRS 45 memmove.h 46 DEPENDS 47 libc.src.__support.integer_operations 48 libc.src.string.memcpy 49) 50 51add_entrypoint_object( 52 memrchr 53 SRCS 54 memrchr.cpp 55 HDRS 56 memrchr.h 57) 58 59add_entrypoint_object( 60 strcat 61 SRCS 62 strcat.cpp 63 HDRS 64 strcat.h 65 DEPENDS 66 .strcpy 67 .string_utils 68) 69 70add_entrypoint_object( 71 strchr 72 SRCS 73 strchr.cpp 74 HDRS 75 strchr.h 76) 77 78add_entrypoint_object( 79 strcmp 80 SRCS 81 strcmp.cpp 82 HDRS 83 strcmp.h 84) 85 86add_entrypoint_object( 87 strcpy 88 SRCS 89 strcpy.cpp 90 HDRS 91 strcpy.h 92 DEPENDS 93 .memcpy 94 .string_utils 95) 96 97add_entrypoint_object( 98 strcspn 99 SRCS 100 strcspn.cpp 101 HDRS 102 strcspn.h 103 DEPENDS 104 .string_utils 105) 106 107add_entrypoint_object( 108 strlen 109 SRCS 110 strlen.cpp 111 HDRS 112 strlen.h 113 DEPENDS 114 libc.include.string 115) 116 117add_entrypoint_object( 118 strncat 119 SRCS 120 strncat.cpp 121 HDRS 122 strncat.h 123 DEPENDS 124 .strncpy 125 .string_utils 126) 127 128add_entrypoint_object( 129 strncmp 130 SRCS 131 strncmp.cpp 132 HDRS 133 strncmp.h 134) 135 136add_entrypoint_object( 137 strncpy 138 SRCS 139 strncpy.cpp 140 HDRS 141 strncpy.h 142) 143 144add_entrypoint_object( 145 strnlen 146 SRCS 147 strnlen.cpp 148 HDRS 149 strnlen.h 150 DEPENDS 151 .string_utils 152) 153 154add_entrypoint_object( 155 strpbrk 156 SRCS 157 strpbrk.cpp 158 HDRS 159 strpbrk.h 160 DEPENDS 161 .string_utils 162) 163 164add_entrypoint_object( 165 strrchr 166 SRCS 167 strrchr.cpp 168 HDRS 169 strrchr.h 170) 171 172add_entrypoint_object( 173 strspn 174 SRCS 175 strspn.cpp 176 HDRS 177 strspn.h 178 DEPENDS 179 libc.utils.CPP.standalone_cpp 180) 181 182add_entrypoint_object( 183 strstr 184 SRCS 185 strstr.cpp 186 HDRS 187 strstr.h 188) 189 190add_entrypoint_object( 191 strtok 192 SRCS 193 strtok.cpp 194 HDRS 195 strtok.h 196 DEPENDS 197 .string_utils 198) 199 200add_entrypoint_object( 201 strtok_r 202 SRCS 203 strtok_r.cpp 204 HDRS 205 strtok_r.h 206 DEPENDS 207 .string_utils 208) 209 210# Helper to define a function with multiple implementations 211# - Computes flags to satisfy required/rejected features and arch, 212# - Declares an entry point, 213# - Attach the REQUIRE_CPU_FEATURES property to the target, 214# - Add the fully qualified target to `${name}_implementations` global property for tests. 215function(add_implementation name impl_name) 216 cmake_parse_arguments( 217 "ADD_IMPL" 218 "" # Optional arguments 219 "" # Single value arguments 220 "REQUIRE;SRCS;HDRS;DEPENDS;COMPILE_OPTIONS" # Multi value arguments 221 ${ARGN}) 222 add_entrypoint_object(${impl_name} 223 NAME ${name} 224 SRCS ${ADD_IMPL_SRCS} 225 HDRS ${ADD_IMPL_HDRS} 226 DEPENDS ${ADD_IMPL_DEPENDS} 227 COMPILE_OPTIONS ${ADD_IMPL_COMPILE_OPTIONS} "SHELL:-mllvm -combiner-global-alias-analysis" 228 ) 229 get_fq_target_name(${impl_name} fq_target_name) 230 set_target_properties(${fq_target_name} PROPERTIES REQUIRE_CPU_FEATURES "${ADD_IMPL_REQUIRE}") 231 set_property(GLOBAL APPEND PROPERTY "${name}_implementations" "${fq_target_name}") 232endfunction() 233 234# ------------------------------------------------------------------------------ 235# bcmp 236# ------------------------------------------------------------------------------ 237 238function(add_bcmp bcmp_name) 239 add_implementation(bcmp ${bcmp_name} 240 SRCS ${LIBC_BCMP_SRC} 241 HDRS ${LIBC_SOURCE_DIR}/src/string/bcmp.h 242 DEPENDS 243 .memory_utils.memory_utils 244 libc.include.string 245 COMPILE_OPTIONS 246 -fno-builtin-memcmp 247 -fno-builtin-bcmp 248 ${ARGN} 249 ) 250endfunction() 251 252if(${LIBC_TARGET_ARCHITECTURE_IS_X86}) 253 set(LIBC_BCMP_SRC ${LIBC_SOURCE_DIR}/src/string/bcmp.cpp) 254 add_bcmp(bcmp_x86_64_opt_sse2 COMPILE_OPTIONS -march=k8 REQUIRE SSE2) 255 add_bcmp(bcmp_x86_64_opt_sse4 COMPILE_OPTIONS -march=nehalem REQUIRE SSE4_2) 256 add_bcmp(bcmp_x86_64_opt_avx2 COMPILE_OPTIONS -march=haswell REQUIRE AVX2) 257 add_bcmp(bcmp_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512F) 258 add_bcmp(bcmp_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 259 add_bcmp(bcmp) 260else() 261 set(LIBC_BCMP_SRC ${LIBC_SOURCE_DIR}/src/string/bcmp.cpp) 262 add_bcmp(bcmp_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 263 add_bcmp(bcmp) 264endif() 265 266# ------------------------------------------------------------------------------ 267# bzero 268# ------------------------------------------------------------------------------ 269 270function(add_bzero bzero_name) 271 add_implementation(bzero ${bzero_name} 272 SRCS ${LIBC_SOURCE_DIR}/src/string/bzero.cpp 273 HDRS ${LIBC_SOURCE_DIR}/src/string/bzero.h 274 DEPENDS 275 .memory_utils.memory_utils 276 libc.include.string 277 COMPILE_OPTIONS 278 -fno-builtin-bzero 279 ${ARGN} 280 ) 281endfunction() 282 283if(${LIBC_TARGET_ARCHITECTURE_IS_X86}) 284 add_bzero(bzero_x86_64_opt_sse2 COMPILE_OPTIONS -march=k8 REQUIRE SSE2) 285 add_bzero(bzero_x86_64_opt_sse4 COMPILE_OPTIONS -march=nehalem REQUIRE SSE4_2) 286 add_bzero(bzero_x86_64_opt_avx2 COMPILE_OPTIONS -march=haswell REQUIRE AVX2) 287 add_bzero(bzero_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512F) 288 add_bzero(bzero_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 289 add_bzero(bzero) 290else() 291 add_bzero(bzero_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 292 add_bzero(bzero) 293endif() 294 295# ------------------------------------------------------------------------------ 296# memcmp 297# ------------------------------------------------------------------------------ 298 299function(add_memcmp memcmp_name) 300 add_implementation(memcmp ${memcmp_name} 301 SRCS ${LIBC_MEMCMP_SRC} 302 HDRS ${LIBC_SOURCE_DIR}/src/string/memcmp.h 303 DEPENDS 304 .memory_utils.memory_utils 305 libc.include.string 306 COMPILE_OPTIONS 307 -fno-builtin-memcmp 308 ${ARGN} 309 ) 310endfunction() 311 312if(${LIBC_TARGET_ARCHITECTURE_IS_X86}) 313 set(LIBC_MEMCMP_SRC ${LIBC_SOURCE_DIR}/src/string/memcmp.cpp) 314 add_memcmp(memcmp_x86_64_opt_sse2 COMPILE_OPTIONS -march=k8 REQUIRE SSE2) 315 add_memcmp(memcmp_x86_64_opt_sse4 COMPILE_OPTIONS -march=nehalem REQUIRE SSE4_2) 316 add_memcmp(memcmp_x86_64_opt_avx2 COMPILE_OPTIONS -march=haswell REQUIRE AVX2) 317 add_memcmp(memcmp_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512F) 318 add_memcmp(memcmp_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 319 add_memcmp(memcmp) 320elseif(${LIBC_TARGET_ARCHITECTURE_IS_AARCH64}) 321 set(LIBC_MEMCMP_SRC ${LIBC_SOURCE_DIR}/src/string/aarch64/memcmp.cpp) 322 add_memcmp(memcmp) 323 add_memcmp(memcmp_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 324else() 325 set(LIBC_MEMCMP_SRC ${LIBC_SOURCE_DIR}/src/string/memcmp.cpp) 326 add_memcmp(memcmp_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 327 add_memcmp(memcmp) 328endif() 329 330# ------------------------------------------------------------------------------ 331# memcpy 332# ------------------------------------------------------------------------------ 333 334function(add_memcpy memcpy_name) 335 add_implementation(memcpy ${memcpy_name} 336 SRCS ${MEMCPY_SRC} 337 HDRS ${LIBC_SOURCE_DIR}/src/string/memcpy.h 338 DEPENDS 339 .memory_utils.memory_utils 340 libc.include.string 341 COMPILE_OPTIONS 342 -fno-builtin-memcpy 343 ${ARGN} 344 ) 345endfunction() 346 347if(${LIBC_TARGET_ARCHITECTURE_IS_X86}) 348 set(MEMCPY_SRC ${LIBC_SOURCE_DIR}/src/string/x86_64/memcpy.cpp) 349 add_memcpy(memcpy_x86_64_opt_sse2 COMPILE_OPTIONS -march=k8 REQUIRE SSE2) 350 add_memcpy(memcpy_x86_64_opt_sse4 COMPILE_OPTIONS -march=nehalem REQUIRE SSE4_2) 351 add_memcpy(memcpy_x86_64_opt_avx2 COMPILE_OPTIONS -march=haswell REQUIRE AVX2) 352 add_memcpy(memcpy_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512F) 353 add_memcpy(memcpy_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 354 add_memcpy(memcpy) 355elseif(${LIBC_TARGET_ARCHITECTURE_IS_AARCH64}) 356 set(MEMCPY_SRC ${LIBC_SOURCE_DIR}/src/string/aarch64/memcpy.cpp) 357 # Disable tail merging as it leads to lower performance. 358 # Note that '-mllvm' needs to be prefixed with 'SHELL:' to prevent CMake flag deduplication. 359 add_memcpy(memcpy_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE} 360 COMPILE_OPTIONS "SHELL:-mllvm --tail-merge-threshold=0") 361 add_memcpy(memcpy COMPILE_OPTIONS "SHELL:-mllvm --tail-merge-threshold=0") 362else() 363 set(MEMCPY_SRC ${LIBC_SOURCE_DIR}/src/string/memcpy.cpp) 364 add_memcpy(memcpy_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 365 add_memcpy(memcpy) 366endif() 367 368# ------------------------------------------------------------------------------ 369# memset 370# ------------------------------------------------------------------------------ 371 372function(add_memset memset_name) 373 add_implementation(memset ${memset_name} 374 SRCS ${MEMSET_SRC} 375 HDRS ${LIBC_SOURCE_DIR}/src/string/memset.h 376 DEPENDS 377 .memory_utils.memory_utils 378 libc.include.string 379 COMPILE_OPTIONS 380 -fno-builtin-memset 381 ${ARGN} 382 ) 383endfunction() 384 385if(${LIBC_TARGET_ARCHITECTURE_IS_X86}) 386 set(MEMSET_SRC ${LIBC_SOURCE_DIR}/src/string/memset.cpp) 387 add_memset(memset_x86_64_opt_sse2 COMPILE_OPTIONS -march=k8 REQUIRE SSE2) 388 add_memset(memset_x86_64_opt_sse4 COMPILE_OPTIONS -march=nehalem REQUIRE SSE4_2) 389 add_memset(memset_x86_64_opt_avx2 COMPILE_OPTIONS -march=haswell REQUIRE AVX2) 390 add_memset(memset_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512F) 391 add_memset(memset_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 392 add_memset(memset) 393elseif(${LIBC_TARGET_ARCHITECTURE_IS_AARCH64}) 394 set(MEMSET_SRC ${LIBC_SOURCE_DIR}/src/string/aarch64/memset.cpp) 395 add_memset(memset_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE} 396 COMPILE_OPTIONS "SHELL:-mllvm --tail-merge-threshold=0") 397 add_memset(memset COMPILE_OPTIONS "SHELL:-mllvm --tail-merge-threshold=0") 398else() 399 set(MEMSET_SRC ${LIBC_SOURCE_DIR}/src/string/memset.cpp) 400 add_memset(memset_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 401 add_memset(memset) 402endif() 403