1add_subdirectory(memory_utils) 2 3add_header_library( 4 string_utils 5 HDRS 6 string_utils.h 7 DEPENDS 8 libc.src.__support.CPP.bitset 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 .memory_utils.memcpy_implementation 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 memrchr 42 SRCS 43 memrchr.cpp 44 HDRS 45 memrchr.h 46) 47 48add_entrypoint_object( 49 stpcpy 50 SRCS 51 stpcpy.cpp 52 HDRS 53 stpcpy.h 54 DEPENDS 55 .mempcpy 56 .string_utils 57) 58 59add_entrypoint_object( 60 stpncpy 61 SRCS 62 stpncpy.cpp 63 HDRS 64 stpncpy.h 65 DEPENDS 66 .memory_utils.memset_implementation 67) 68 69add_entrypoint_object( 70 strcat 71 SRCS 72 strcat.cpp 73 HDRS 74 strcat.h 75 DEPENDS 76 .strcpy 77 .string_utils 78) 79 80add_entrypoint_object( 81 strchr 82 SRCS 83 strchr.cpp 84 HDRS 85 strchr.h 86) 87 88add_entrypoint_object( 89 strcmp 90 SRCS 91 strcmp.cpp 92 HDRS 93 strcmp.h 94) 95 96add_entrypoint_object( 97 strcpy 98 SRCS 99 strcpy.cpp 100 HDRS 101 strcpy.h 102 DEPENDS 103 .memory_utils.memcpy_implementation 104 .string_utils 105) 106 107add_entrypoint_object( 108 strcspn 109 SRCS 110 strcspn.cpp 111 HDRS 112 strcspn.h 113 DEPENDS 114 .string_utils 115) 116 117add_entrypoint_object( 118 strdup 119 SRCS 120 strdup.cpp 121 HDRS 122 strdup.h 123 DEPENDS 124 .memory_utils.memcpy_implementation 125 .string_utils 126 libc.include.stdlib 127) 128 129add_entrypoint_object( 130 strlcpy 131 SRCS 132 strlcpy.cpp 133 HDRS 134 strlcpy.h 135 DEPENDS 136 .memory_utils.memcpy_implementation 137 .memory_utils.memset_implementation 138 .string_utils 139 libc.include.string 140) 141 142add_entrypoint_object( 143 strlen 144 SRCS 145 strlen.cpp 146 HDRS 147 strlen.h 148 DEPENDS 149 libc.include.string 150) 151 152add_entrypoint_object( 153 strncat 154 SRCS 155 strncat.cpp 156 HDRS 157 strncat.h 158 DEPENDS 159 .strncpy 160 .string_utils 161) 162 163add_entrypoint_object( 164 strncmp 165 SRCS 166 strncmp.cpp 167 HDRS 168 strncmp.h 169) 170 171add_entrypoint_object( 172 strncpy 173 SRCS 174 strncpy.cpp 175 HDRS 176 strncpy.h 177) 178 179add_entrypoint_object( 180 strndup 181 SRCS 182 strndup.cpp 183 HDRS 184 strndup.h 185 DEPENDS 186 .memory_utils.memcpy_implementation 187 .string_utils 188 libc.include.stdlib 189) 190 191add_entrypoint_object( 192 strnlen 193 SRCS 194 strnlen.cpp 195 HDRS 196 strnlen.h 197 DEPENDS 198 .string_utils 199) 200 201add_entrypoint_object( 202 strpbrk 203 SRCS 204 strpbrk.cpp 205 HDRS 206 strpbrk.h 207 DEPENDS 208 .string_utils 209) 210 211add_entrypoint_object( 212 strrchr 213 SRCS 214 strrchr.cpp 215 HDRS 216 strrchr.h 217) 218 219add_entrypoint_object( 220 strspn 221 SRCS 222 strspn.cpp 223 HDRS 224 strspn.h 225 DEPENDS 226 libc.src.__support.CPP.bitset 227) 228 229add_entrypoint_object( 230 strstr 231 SRCS 232 strstr.cpp 233 HDRS 234 strstr.h 235) 236 237add_entrypoint_object( 238 strtok 239 SRCS 240 strtok.cpp 241 HDRS 242 strtok.h 243 DEPENDS 244 .string_utils 245) 246 247add_entrypoint_object( 248 strtok_r 249 SRCS 250 strtok_r.cpp 251 HDRS 252 strtok_r.h 253 DEPENDS 254 .string_utils 255) 256 257# Helper to define a function with multiple implementations 258# - Computes flags to satisfy required/rejected features and arch, 259# - Declares an entry point, 260# - Attach the REQUIRE_CPU_FEATURES property to the target, 261# - Add the fully qualified target to `${name}_implementations` global property for tests. 262function(add_implementation name impl_name) 263 cmake_parse_arguments( 264 "ADD_IMPL" 265 "" # Optional arguments 266 "" # Single value arguments 267 "REQUIRE;SRCS;HDRS;DEPENDS;COMPILE_OPTIONS;MLLVM_COMPILE_OPTIONS" # Multi value arguments 268 ${ARGN}) 269 270 if("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") 271 list(APPEND ADD_IMPL_MLLVM_COMPILE_OPTIONS "-combiner-global-alias-analysis") 272 # Note that '-mllvm' needs to be prefixed with 'SHELL:' to prevent CMake flag deduplication. 273 foreach(opt IN LISTS ADD_IMPL_MLLVM_COMPILE_OPTIONS) 274 list(APPEND ADD_IMPL_COMPILE_OPTIONS "SHELL:-mllvm ${opt}") 275 endforeach() 276 endif() 277 278 add_entrypoint_object(${impl_name} 279 NAME ${name} 280 SRCS ${ADD_IMPL_SRCS} 281 HDRS ${ADD_IMPL_HDRS} 282 DEPENDS ${ADD_IMPL_DEPENDS} 283 COMPILE_OPTIONS ${ADD_IMPL_COMPILE_OPTIONS} 284 ) 285 get_fq_target_name(${impl_name} fq_target_name) 286 set_target_properties(${fq_target_name} PROPERTIES REQUIRE_CPU_FEATURES "${ADD_IMPL_REQUIRE}") 287 set_property(GLOBAL APPEND PROPERTY "${name}_implementations" "${fq_target_name}") 288endfunction() 289 290# ------------------------------------------------------------------------------ 291# bcmp 292# ------------------------------------------------------------------------------ 293 294function(add_bcmp bcmp_name) 295 add_implementation(bcmp ${bcmp_name} 296 SRCS ${LIBC_SOURCE_DIR}/src/string/bcmp.cpp 297 HDRS ${LIBC_SOURCE_DIR}/src/string/bcmp.h 298 DEPENDS 299 .memory_utils.memory_utils 300 libc.include.string 301 COMPILE_OPTIONS 302 -fno-builtin-memcmp 303 -fno-builtin-bcmp 304 ${ARGN} 305 ) 306endfunction() 307 308if(${LIBC_TARGET_ARCHITECTURE_IS_X86}) 309 add_bcmp(bcmp_x86_64_opt_sse2 COMPILE_OPTIONS -march=k8 REQUIRE SSE2) 310 add_bcmp(bcmp_x86_64_opt_sse4 COMPILE_OPTIONS -march=nehalem REQUIRE SSE4_2) 311 add_bcmp(bcmp_x86_64_opt_avx2 COMPILE_OPTIONS -march=haswell REQUIRE AVX2) 312 add_bcmp(bcmp_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512F) 313 add_bcmp(bcmp_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 314 add_bcmp(bcmp) 315else() 316 add_bcmp(bcmp_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 317 add_bcmp(bcmp) 318endif() 319 320# ------------------------------------------------------------------------------ 321# bzero 322# ------------------------------------------------------------------------------ 323 324function(add_bzero bzero_name) 325 add_implementation(bzero ${bzero_name} 326 SRCS ${LIBC_SOURCE_DIR}/src/string/bzero.cpp 327 HDRS ${LIBC_SOURCE_DIR}/src/string/bzero.h 328 DEPENDS 329 .memory_utils.memset_implementation 330 libc.include.string 331 COMPILE_OPTIONS 332 -fno-builtin-bzero 333 ${ARGN} 334 ) 335endfunction() 336 337if(${LIBC_TARGET_ARCHITECTURE_IS_X86}) 338 add_bzero(bzero_x86_64_opt_sse2 COMPILE_OPTIONS -march=k8 REQUIRE SSE2) 339 add_bzero(bzero_x86_64_opt_sse4 COMPILE_OPTIONS -march=nehalem REQUIRE SSE4_2) 340 add_bzero(bzero_x86_64_opt_avx2 COMPILE_OPTIONS -march=haswell REQUIRE AVX2) 341 add_bzero(bzero_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512F) 342 add_bzero(bzero_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 343 add_bzero(bzero) 344else() 345 add_bzero(bzero_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 346 add_bzero(bzero) 347endif() 348 349# ------------------------------------------------------------------------------ 350# memcmp 351# ------------------------------------------------------------------------------ 352 353function(add_memcmp memcmp_name) 354 add_implementation(memcmp ${memcmp_name} 355 SRCS ${LIBC_SOURCE_DIR}/src/string/memcmp.cpp 356 HDRS ${LIBC_SOURCE_DIR}/src/string/memcmp.h 357 DEPENDS 358 .memory_utils.memcmp_implementation 359 libc.include.string 360 COMPILE_OPTIONS 361 -fno-builtin-memcmp 362 ${ARGN} 363 ) 364endfunction() 365 366if(${LIBC_TARGET_ARCHITECTURE_IS_X86}) 367 add_memcmp(memcmp_x86_64_opt_sse2 COMPILE_OPTIONS -march=k8 REQUIRE SSE2) 368 add_memcmp(memcmp_x86_64_opt_sse4 COMPILE_OPTIONS -march=nehalem REQUIRE SSE4_2) 369 add_memcmp(memcmp_x86_64_opt_avx2 COMPILE_OPTIONS -march=haswell REQUIRE AVX2) 370 add_memcmp(memcmp_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512F) 371 add_memcmp(memcmp_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 372 add_memcmp(memcmp) 373elseif(${LIBC_TARGET_ARCHITECTURE_IS_AARCH64}) 374 add_memcmp(memcmp_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 375 add_memcmp(memcmp) 376else() 377 add_memcmp(memcmp_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 378 add_memcmp(memcmp) 379endif() 380 381# ------------------------------------------------------------------------------ 382# memcpy 383# ------------------------------------------------------------------------------ 384 385function(add_memcpy memcpy_name) 386 add_implementation(memcpy ${memcpy_name} 387 SRCS ${LIBC_SOURCE_DIR}/src/string/memcpy.cpp 388 HDRS ${LIBC_SOURCE_DIR}/src/string/memcpy.h 389 DEPENDS 390 .memory_utils.memcpy_implementation 391 libc.include.string 392 COMPILE_OPTIONS 393 -fno-builtin-memcpy 394 ${ARGN} 395 ) 396endfunction() 397 398if(${LIBC_TARGET_ARCHITECTURE_IS_X86}) 399 add_memcpy(memcpy_x86_64_opt_sse2 COMPILE_OPTIONS -march=k8 REQUIRE SSE2) 400 add_memcpy(memcpy_x86_64_opt_sse4 COMPILE_OPTIONS -march=nehalem REQUIRE SSE4_2) 401 add_memcpy(memcpy_x86_64_opt_avx2 COMPILE_OPTIONS -march=haswell REQUIRE AVX2) 402 add_memcpy(memcpy_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512F) 403 add_memcpy(memcpy_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 404 add_memcpy(memcpy) 405elseif(${LIBC_TARGET_ARCHITECTURE_IS_AARCH64}) 406 # Disable tail merging as it leads to lower performance. 407 add_memcpy(memcpy_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE} 408 MLLVM_COMPILE_OPTIONS "-tail-merge-threshold=0") 409 add_memcpy(memcpy MLLVM_COMPILE_OPTIONS "-tail-merge-threshold=0") 410else() 411 add_memcpy(memcpy_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 412 add_memcpy(memcpy) 413endif() 414 415# ------------------------------------------------------------------------------ 416# memmove 417# ------------------------------------------------------------------------------ 418 419function(add_memmove memmove_name) 420 add_implementation(memmove ${memmove_name} 421 SRCS ${LIBC_SOURCE_DIR}/src/string/memmove.cpp 422 HDRS ${LIBC_SOURCE_DIR}/src/string/memmove.h 423 DEPENDS 424 .memory_utils.memory_utils 425 libc.include.string 426 COMPILE_OPTIONS 427 -fno-builtin 428 ${ARGN} 429 ) 430endfunction() 431 432if(${LIBC_TARGET_ARCHITECTURE_IS_X86}) 433 add_memmove(memmove_x86_64_opt_sse2 COMPILE_OPTIONS -march=k8 REQUIRE SSE2) 434 add_memmove(memmove_x86_64_opt_sse4 COMPILE_OPTIONS -march=nehalem REQUIRE SSE4_2) 435 add_memmove(memmove_x86_64_opt_avx2 COMPILE_OPTIONS -march=haswell REQUIRE AVX2) 436 add_memmove(memmove_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512F) 437 add_memmove(memmove_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 438 add_memmove(memmove) 439elseif(${LIBC_TARGET_ARCHITECTURE_IS_AARCH64}) 440 # Disable tail merging as it leads to lower performance. 441 add_memmove(memmove_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE} 442 MLLVM_COMPILE_OPTIONS "-tail-merge-threshold=0") 443 add_memmove(memmove MLLVM_COMPILE_OPTIONS "-tail-merge-threshold=0") 444else() 445 add_memmove(memmove_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 446 add_memmove(memmove) 447endif() 448 449# ------------------------------------------------------------------------------ 450# memset 451# ------------------------------------------------------------------------------ 452 453function(add_memset memset_name) 454 add_implementation(memset ${memset_name} 455 SRCS ${LIBC_SOURCE_DIR}/src/string/memset.cpp 456 HDRS ${LIBC_SOURCE_DIR}/src/string/memset.h 457 DEPENDS 458 .memory_utils.memset_implementation 459 libc.include.string 460 COMPILE_OPTIONS 461 -fno-builtin-memset 462 ${ARGN} 463 ) 464endfunction() 465 466if(${LIBC_TARGET_ARCHITECTURE_IS_X86}) 467 add_memset(memset_x86_64_opt_sse2 COMPILE_OPTIONS -march=k8 REQUIRE SSE2) 468 add_memset(memset_x86_64_opt_sse4 COMPILE_OPTIONS -march=nehalem REQUIRE SSE4_2) 469 add_memset(memset_x86_64_opt_avx2 COMPILE_OPTIONS -march=haswell REQUIRE AVX2) 470 add_memset(memset_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512F) 471 add_memset(memset_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 472 add_memset(memset) 473elseif(${LIBC_TARGET_ARCHITECTURE_IS_AARCH64}) 474 # Disable tail merging as it leads to lower performance. 475 add_memset(memset_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE} 476 MLLVM_COMPILE_OPTIONS "-tail-merge-threshold=0") 477 add_memset(memset MLLVM_COMPILE_OPTIONS "-tail-merge-threshold=0") 478else() 479 add_memset(memset_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 480 add_memset(memset) 481endif() 482