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 # Note that '-mllvm' needs to be prefixed with 'SHELL:' to prevent CMake flag deduplication. 283 foreach(opt IN LISTS ADD_IMPL_MLLVM_COMPILE_OPTIONS) 284 list(APPEND ADD_IMPL_COMPILE_OPTIONS "SHELL:-mllvm ${opt}") 285 endforeach() 286 endif() 287 288 add_entrypoint_object(${impl_name} 289 NAME ${name} 290 SRCS ${ADD_IMPL_SRCS} 291 HDRS ${ADD_IMPL_HDRS} 292 DEPENDS ${ADD_IMPL_DEPENDS} 293 COMPILE_OPTIONS ${ADD_IMPL_COMPILE_OPTIONS} 294 ) 295 get_fq_target_name(${impl_name} fq_target_name) 296 set_target_properties(${fq_target_name} PROPERTIES REQUIRE_CPU_FEATURES "${ADD_IMPL_REQUIRE}") 297 set_property(GLOBAL APPEND PROPERTY "${name}_implementations" "${fq_target_name}") 298endfunction() 299 300# ------------------------------------------------------------------------------ 301# bcmp 302# ------------------------------------------------------------------------------ 303 304function(add_bcmp bcmp_name) 305 add_implementation(bcmp ${bcmp_name} 306 SRCS ${LIBC_SOURCE_DIR}/src/string/bcmp.cpp 307 HDRS ${LIBC_SOURCE_DIR}/src/string/bcmp.h 308 DEPENDS 309 .memory_utils.memory_utils 310 libc.include.string 311 COMPILE_OPTIONS 312 -fno-builtin-memcmp 313 -fno-builtin-bcmp 314 ${ARGN} 315 ) 316endfunction() 317 318if(${LIBC_TARGET_ARCHITECTURE_IS_X86}) 319 add_bcmp(bcmp_x86_64_opt_sse2 COMPILE_OPTIONS -march=k8 REQUIRE SSE2) 320 add_bcmp(bcmp_x86_64_opt_sse4 COMPILE_OPTIONS -march=nehalem REQUIRE SSE4_2) 321 add_bcmp(bcmp_x86_64_opt_avx2 COMPILE_OPTIONS -march=haswell REQUIRE AVX2) 322 add_bcmp(bcmp_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512F) 323 add_bcmp(bcmp_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 324 add_bcmp(bcmp) 325else() 326 add_bcmp(bcmp_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 327 add_bcmp(bcmp) 328endif() 329 330# ------------------------------------------------------------------------------ 331# bzero 332# ------------------------------------------------------------------------------ 333 334function(add_bzero bzero_name) 335 add_implementation(bzero ${bzero_name} 336 SRCS ${LIBC_SOURCE_DIR}/src/string/bzero.cpp 337 HDRS ${LIBC_SOURCE_DIR}/src/string/bzero.h 338 DEPENDS 339 .memory_utils.memset_implementation 340 libc.include.string 341 COMPILE_OPTIONS 342 -fno-builtin-bzero 343 ${ARGN} 344 ) 345endfunction() 346 347if(${LIBC_TARGET_ARCHITECTURE_IS_X86}) 348 add_bzero(bzero_x86_64_opt_sse2 COMPILE_OPTIONS -march=k8 REQUIRE SSE2) 349 add_bzero(bzero_x86_64_opt_sse4 COMPILE_OPTIONS -march=nehalem REQUIRE SSE4_2) 350 add_bzero(bzero_x86_64_opt_avx2 COMPILE_OPTIONS -march=haswell REQUIRE AVX2) 351 add_bzero(bzero_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512F) 352 add_bzero(bzero_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 353 add_bzero(bzero) 354else() 355 add_bzero(bzero_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 356 add_bzero(bzero) 357endif() 358 359# ------------------------------------------------------------------------------ 360# memcmp 361# ------------------------------------------------------------------------------ 362 363function(add_memcmp memcmp_name) 364 add_implementation(memcmp ${memcmp_name} 365 SRCS ${LIBC_SOURCE_DIR}/src/string/memcmp.cpp 366 HDRS ${LIBC_SOURCE_DIR}/src/string/memcmp.h 367 DEPENDS 368 .memory_utils.memcmp_implementation 369 libc.include.string 370 COMPILE_OPTIONS 371 -fno-builtin-memcmp 372 ${ARGN} 373 ) 374endfunction() 375 376if(${LIBC_TARGET_ARCHITECTURE_IS_X86}) 377 add_memcmp(memcmp_x86_64_opt_sse2 COMPILE_OPTIONS -march=k8 REQUIRE SSE2) 378 add_memcmp(memcmp_x86_64_opt_sse4 COMPILE_OPTIONS -march=nehalem REQUIRE SSE4_2) 379 add_memcmp(memcmp_x86_64_opt_avx2 COMPILE_OPTIONS -march=haswell REQUIRE AVX2) 380 add_memcmp(memcmp_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512F) 381 add_memcmp(memcmp_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 382 add_memcmp(memcmp) 383elseif(${LIBC_TARGET_ARCHITECTURE_IS_AARCH64}) 384 add_memcmp(memcmp_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 385 add_memcmp(memcmp) 386else() 387 add_memcmp(memcmp_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 388 add_memcmp(memcmp) 389endif() 390 391# ------------------------------------------------------------------------------ 392# memcpy 393# ------------------------------------------------------------------------------ 394 395function(add_memcpy memcpy_name) 396 add_implementation(memcpy ${memcpy_name} 397 SRCS ${LIBC_SOURCE_DIR}/src/string/memcpy.cpp 398 HDRS ${LIBC_SOURCE_DIR}/src/string/memcpy.h 399 DEPENDS 400 .memory_utils.memcpy_implementation 401 libc.include.string 402 COMPILE_OPTIONS 403 -fno-builtin-memcpy 404 ${ARGN} 405 ) 406endfunction() 407 408if(${LIBC_TARGET_ARCHITECTURE_IS_X86}) 409 add_memcpy(memcpy_x86_64_opt_sse2 COMPILE_OPTIONS -march=k8 REQUIRE SSE2) 410 add_memcpy(memcpy_x86_64_opt_sse4 COMPILE_OPTIONS -march=nehalem REQUIRE SSE4_2) 411 add_memcpy(memcpy_x86_64_opt_avx2 COMPILE_OPTIONS -march=haswell REQUIRE AVX2) 412 add_memcpy(memcpy_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512F) 413 add_memcpy(memcpy_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 414 add_memcpy(memcpy) 415elseif(${LIBC_TARGET_ARCHITECTURE_IS_AARCH64}) 416 # Disable tail merging as it leads to lower performance. 417 add_memcpy(memcpy_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE} 418 MLLVM_COMPILE_OPTIONS "-tail-merge-threshold=0") 419 add_memcpy(memcpy MLLVM_COMPILE_OPTIONS "-tail-merge-threshold=0") 420else() 421 add_memcpy(memcpy_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 422 add_memcpy(memcpy) 423endif() 424 425# ------------------------------------------------------------------------------ 426# memmove 427# ------------------------------------------------------------------------------ 428 429function(add_memmove memmove_name) 430 add_implementation(memmove ${memmove_name} 431 SRCS ${LIBC_SOURCE_DIR}/src/string/memmove.cpp 432 HDRS ${LIBC_SOURCE_DIR}/src/string/memmove.h 433 DEPENDS 434 .memory_utils.memory_utils 435 libc.include.string 436 COMPILE_OPTIONS 437 -fno-builtin 438 ${ARGN} 439 ) 440endfunction() 441 442if(${LIBC_TARGET_ARCHITECTURE_IS_X86}) 443 add_memmove(memmove_x86_64_opt_sse2 COMPILE_OPTIONS -march=k8 REQUIRE SSE2) 444 add_memmove(memmove_x86_64_opt_sse4 COMPILE_OPTIONS -march=nehalem REQUIRE SSE4_2) 445 add_memmove(memmove_x86_64_opt_avx2 COMPILE_OPTIONS -march=haswell REQUIRE AVX2) 446 add_memmove(memmove_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512F) 447 add_memmove(memmove_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 448 add_memmove(memmove) 449elseif(${LIBC_TARGET_ARCHITECTURE_IS_AARCH64}) 450 # Disable tail merging as it leads to lower performance. 451 add_memmove(memmove_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE} 452 MLLVM_COMPILE_OPTIONS "-tail-merge-threshold=0") 453 add_memmove(memmove MLLVM_COMPILE_OPTIONS "-tail-merge-threshold=0") 454else() 455 add_memmove(memmove_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 456 add_memmove(memmove) 457endif() 458 459# ------------------------------------------------------------------------------ 460# memset 461# ------------------------------------------------------------------------------ 462 463function(add_memset memset_name) 464 add_implementation(memset ${memset_name} 465 SRCS ${LIBC_SOURCE_DIR}/src/string/memset.cpp 466 HDRS ${LIBC_SOURCE_DIR}/src/string/memset.h 467 DEPENDS 468 .memory_utils.memset_implementation 469 libc.include.string 470 COMPILE_OPTIONS 471 -fno-builtin-memset 472 ${ARGN} 473 ) 474endfunction() 475 476if(${LIBC_TARGET_ARCHITECTURE_IS_X86}) 477 add_memset(memset_x86_64_opt_sse2 COMPILE_OPTIONS -march=k8 REQUIRE SSE2) 478 add_memset(memset_x86_64_opt_sse4 COMPILE_OPTIONS -march=nehalem REQUIRE SSE4_2) 479 add_memset(memset_x86_64_opt_avx2 COMPILE_OPTIONS -march=haswell REQUIRE AVX2) 480 add_memset(memset_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512F) 481 add_memset(memset_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 482 add_memset(memset) 483elseif(${LIBC_TARGET_ARCHITECTURE_IS_AARCH64}) 484 # Disable tail merging as it leads to lower performance. 485 add_memset(memset_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE} 486 MLLVM_COMPILE_OPTIONS "-tail-merge-threshold=0") 487 add_memset(memset MLLVM_COMPILE_OPTIONS "-tail-merge-threshold=0") 488else() 489 add_memset(memset_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 490 add_memset(memset) 491endif() 492