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