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 ${ARGN} 312 ) 313endfunction() 314 315if(${LIBC_TARGET_ARCHITECTURE_IS_X86}) 316 add_bcmp(bcmp_x86_64_opt_sse2 COMPILE_OPTIONS -march=k8 REQUIRE SSE2) 317 add_bcmp(bcmp_x86_64_opt_sse4 COMPILE_OPTIONS -march=nehalem REQUIRE SSE4_2) 318 add_bcmp(bcmp_x86_64_opt_avx2 COMPILE_OPTIONS -march=haswell REQUIRE AVX2) 319 add_bcmp(bcmp_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512F) 320 add_bcmp(bcmp_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 321 add_bcmp(bcmp) 322else() 323 add_bcmp(bcmp_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 324 add_bcmp(bcmp) 325endif() 326 327# ------------------------------------------------------------------------------ 328# bzero 329# ------------------------------------------------------------------------------ 330 331function(add_bzero bzero_name) 332 add_implementation(bzero ${bzero_name} 333 SRCS ${LIBC_SOURCE_DIR}/src/string/bzero.cpp 334 HDRS ${LIBC_SOURCE_DIR}/src/string/bzero.h 335 DEPENDS 336 .memory_utils.memset_implementation 337 libc.include.string 338 ${ARGN} 339 ) 340endfunction() 341 342if(${LIBC_TARGET_ARCHITECTURE_IS_X86}) 343 add_bzero(bzero_x86_64_opt_sse2 COMPILE_OPTIONS -march=k8 REQUIRE SSE2) 344 add_bzero(bzero_x86_64_opt_sse4 COMPILE_OPTIONS -march=nehalem REQUIRE SSE4_2) 345 add_bzero(bzero_x86_64_opt_avx2 COMPILE_OPTIONS -march=haswell REQUIRE AVX2) 346 add_bzero(bzero_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512F) 347 add_bzero(bzero_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 348 add_bzero(bzero) 349else() 350 add_bzero(bzero_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 351 add_bzero(bzero) 352endif() 353 354# ------------------------------------------------------------------------------ 355# memcmp 356# ------------------------------------------------------------------------------ 357 358function(add_memcmp memcmp_name) 359 add_implementation(memcmp ${memcmp_name} 360 SRCS ${LIBC_SOURCE_DIR}/src/string/memcmp.cpp 361 HDRS ${LIBC_SOURCE_DIR}/src/string/memcmp.h 362 DEPENDS 363 .memory_utils.memcmp_implementation 364 libc.include.string 365 ${ARGN} 366 ) 367endfunction() 368 369if(${LIBC_TARGET_ARCHITECTURE_IS_X86}) 370 add_memcmp(memcmp_x86_64_opt_sse2 COMPILE_OPTIONS -march=k8 REQUIRE SSE2) 371 add_memcmp(memcmp_x86_64_opt_sse4 COMPILE_OPTIONS -march=nehalem REQUIRE SSE4_2) 372 add_memcmp(memcmp_x86_64_opt_avx2 COMPILE_OPTIONS -march=haswell REQUIRE AVX2) 373 add_memcmp(memcmp_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512F) 374 add_memcmp(memcmp_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 375 add_memcmp(memcmp) 376elseif(${LIBC_TARGET_ARCHITECTURE_IS_AARCH64}) 377 add_memcmp(memcmp_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 378 add_memcmp(memcmp) 379else() 380 add_memcmp(memcmp_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 381 add_memcmp(memcmp) 382endif() 383 384# ------------------------------------------------------------------------------ 385# memcpy 386# ------------------------------------------------------------------------------ 387 388function(add_memcpy memcpy_name) 389 add_implementation(memcpy ${memcpy_name} 390 SRCS ${LIBC_SOURCE_DIR}/src/string/memcpy.cpp 391 HDRS ${LIBC_SOURCE_DIR}/src/string/memcpy.h 392 DEPENDS 393 .memory_utils.memcpy_implementation 394 libc.include.string 395 ${ARGN} 396 ) 397endfunction() 398 399if(${LIBC_TARGET_ARCHITECTURE_IS_X86}) 400 add_memcpy(memcpy_x86_64_opt_sse2 COMPILE_OPTIONS -march=k8 REQUIRE SSE2) 401 add_memcpy(memcpy_x86_64_opt_sse4 COMPILE_OPTIONS -march=nehalem REQUIRE SSE4_2) 402 add_memcpy(memcpy_x86_64_opt_avx2 COMPILE_OPTIONS -march=haswell REQUIRE AVX2) 403 add_memcpy(memcpy_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512F) 404 add_memcpy(memcpy_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 405 add_memcpy(memcpy) 406elseif(${LIBC_TARGET_ARCHITECTURE_IS_AARCH64}) 407 # Disable tail merging as it leads to lower performance. 408 add_memcpy(memcpy_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE} 409 MLLVM_COMPILE_OPTIONS "-tail-merge-threshold=0") 410 add_memcpy(memcpy MLLVM_COMPILE_OPTIONS "-tail-merge-threshold=0") 411else() 412 add_memcpy(memcpy_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 413 add_memcpy(memcpy) 414endif() 415 416# ------------------------------------------------------------------------------ 417# memmove 418# ------------------------------------------------------------------------------ 419 420function(add_memmove memmove_name) 421 add_implementation(memmove ${memmove_name} 422 SRCS ${LIBC_SOURCE_DIR}/src/string/memmove.cpp 423 HDRS ${LIBC_SOURCE_DIR}/src/string/memmove.h 424 DEPENDS 425 .memory_utils.memory_utils 426 libc.include.string 427 ${ARGN} 428 ) 429endfunction() 430 431if(${LIBC_TARGET_ARCHITECTURE_IS_X86}) 432 add_memmove(memmove_x86_64_opt_sse2 COMPILE_OPTIONS -march=k8 REQUIRE SSE2) 433 add_memmove(memmove_x86_64_opt_sse4 COMPILE_OPTIONS -march=nehalem REQUIRE SSE4_2) 434 add_memmove(memmove_x86_64_opt_avx2 COMPILE_OPTIONS -march=haswell REQUIRE AVX2) 435 add_memmove(memmove_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512F) 436 add_memmove(memmove_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 437 add_memmove(memmove) 438elseif(${LIBC_TARGET_ARCHITECTURE_IS_AARCH64}) 439 # Disable tail merging as it leads to lower performance. 440 add_memmove(memmove_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE} 441 MLLVM_COMPILE_OPTIONS "-tail-merge-threshold=0") 442 add_memmove(memmove MLLVM_COMPILE_OPTIONS "-tail-merge-threshold=0") 443else() 444 add_memmove(memmove_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 445 add_memmove(memmove) 446endif() 447 448# ------------------------------------------------------------------------------ 449# memset 450# ------------------------------------------------------------------------------ 451 452function(add_memset memset_name) 453 add_implementation(memset ${memset_name} 454 SRCS ${LIBC_SOURCE_DIR}/src/string/memset.cpp 455 HDRS ${LIBC_SOURCE_DIR}/src/string/memset.h 456 DEPENDS 457 .memory_utils.memset_implementation 458 libc.include.string 459 ${ARGN} 460 ) 461endfunction() 462 463if(${LIBC_TARGET_ARCHITECTURE_IS_X86}) 464 add_memset(memset_x86_64_opt_sse2 COMPILE_OPTIONS -march=k8 REQUIRE SSE2) 465 add_memset(memset_x86_64_opt_sse4 COMPILE_OPTIONS -march=nehalem REQUIRE SSE4_2) 466 add_memset(memset_x86_64_opt_avx2 COMPILE_OPTIONS -march=haswell REQUIRE AVX2) 467 add_memset(memset_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512F) 468 add_memset(memset_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 469 add_memset(memset) 470elseif(${LIBC_TARGET_ARCHITECTURE_IS_AARCH64}) 471 # Disable tail merging as it leads to lower performance. 472 add_memset(memset_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE} 473 MLLVM_COMPILE_OPTIONS "-tail-merge-threshold=0") 474 add_memset(memset MLLVM_COMPILE_OPTIONS "-tail-merge-threshold=0") 475else() 476 add_memset(memset_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 477 add_memset(memset) 478endif() 479