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