1add_subdirectory(memory_utils) 2 3add_header_library( 4 string_utils 5 HDRS 6 string_utils.h 7 DEPENDS 8 libc.src.__support.CPP.standalone_cpp 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.standalone_cpp 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" # Multi value arguments 255 ${ARGN}) 256 add_entrypoint_object(${impl_name} 257 NAME ${name} 258 SRCS ${ADD_IMPL_SRCS} 259 HDRS ${ADD_IMPL_HDRS} 260 DEPENDS ${ADD_IMPL_DEPENDS} 261 COMPILE_OPTIONS ${ADD_IMPL_COMPILE_OPTIONS} "SHELL:-mllvm -combiner-global-alias-analysis" 262 ) 263 get_fq_target_name(${impl_name} fq_target_name) 264 set_target_properties(${fq_target_name} PROPERTIES REQUIRE_CPU_FEATURES "${ADD_IMPL_REQUIRE}") 265 set_property(GLOBAL APPEND PROPERTY "${name}_implementations" "${fq_target_name}") 266endfunction() 267 268# ------------------------------------------------------------------------------ 269# bcmp 270# ------------------------------------------------------------------------------ 271 272function(add_bcmp bcmp_name) 273 add_implementation(bcmp ${bcmp_name} 274 SRCS ${LIBC_SOURCE_DIR}/src/string/bcmp.cpp 275 HDRS ${LIBC_SOURCE_DIR}/src/string/bcmp.h 276 DEPENDS 277 .memory_utils.memory_utils 278 libc.include.string 279 COMPILE_OPTIONS 280 -fno-builtin-memcmp 281 -fno-builtin-bcmp 282 ${ARGN} 283 ) 284endfunction() 285 286if(${LIBC_TARGET_ARCHITECTURE_IS_X86}) 287 add_bcmp(bcmp_x86_64_opt_sse2 COMPILE_OPTIONS -march=k8 REQUIRE SSE2) 288 add_bcmp(bcmp_x86_64_opt_sse4 COMPILE_OPTIONS -march=nehalem REQUIRE SSE4_2) 289 add_bcmp(bcmp_x86_64_opt_avx2 COMPILE_OPTIONS -march=haswell REQUIRE AVX2) 290 add_bcmp(bcmp_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512F) 291 add_bcmp(bcmp_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 292 add_bcmp(bcmp) 293else() 294 add_bcmp(bcmp_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 295 add_bcmp(bcmp) 296endif() 297 298# ------------------------------------------------------------------------------ 299# bzero 300# ------------------------------------------------------------------------------ 301 302function(add_bzero bzero_name) 303 add_implementation(bzero ${bzero_name} 304 SRCS ${LIBC_SOURCE_DIR}/src/string/bzero.cpp 305 HDRS ${LIBC_SOURCE_DIR}/src/string/bzero.h 306 DEPENDS 307 .memory_utils.memset_implementation 308 libc.include.string 309 COMPILE_OPTIONS 310 -fno-builtin-bzero 311 ${ARGN} 312 ) 313endfunction() 314 315if(${LIBC_TARGET_ARCHITECTURE_IS_X86}) 316 add_bzero(bzero_x86_64_opt_sse2 COMPILE_OPTIONS -march=k8 REQUIRE SSE2) 317 add_bzero(bzero_x86_64_opt_sse4 COMPILE_OPTIONS -march=nehalem REQUIRE SSE4_2) 318 add_bzero(bzero_x86_64_opt_avx2 COMPILE_OPTIONS -march=haswell REQUIRE AVX2) 319 add_bzero(bzero_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512F) 320 add_bzero(bzero_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 321 add_bzero(bzero) 322else() 323 add_bzero(bzero_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 324 add_bzero(bzero) 325endif() 326 327# ------------------------------------------------------------------------------ 328# memcmp 329# ------------------------------------------------------------------------------ 330 331function(add_memcmp memcmp_name) 332 add_implementation(memcmp ${memcmp_name} 333 SRCS ${LIBC_SOURCE_DIR}/src/string/memcmp.cpp 334 HDRS ${LIBC_SOURCE_DIR}/src/string/memcmp.h 335 DEPENDS 336 .memory_utils.memcmp_implementation 337 libc.include.string 338 COMPILE_OPTIONS 339 -fno-builtin-memcmp 340 ${ARGN} 341 ) 342endfunction() 343 344if(${LIBC_TARGET_ARCHITECTURE_IS_X86}) 345 add_memcmp(memcmp_x86_64_opt_sse2 COMPILE_OPTIONS -march=k8 REQUIRE SSE2) 346 add_memcmp(memcmp_x86_64_opt_sse4 COMPILE_OPTIONS -march=nehalem REQUIRE SSE4_2) 347 add_memcmp(memcmp_x86_64_opt_avx2 COMPILE_OPTIONS -march=haswell REQUIRE AVX2) 348 add_memcmp(memcmp_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512F) 349 add_memcmp(memcmp_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 350 add_memcmp(memcmp) 351elseif(${LIBC_TARGET_ARCHITECTURE_IS_AARCH64}) 352 add_memcmp(memcmp_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 353 add_memcmp(memcmp) 354else() 355 add_memcmp(memcmp_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 356 add_memcmp(memcmp) 357endif() 358 359# ------------------------------------------------------------------------------ 360# memcpy 361# ------------------------------------------------------------------------------ 362 363function(add_memcpy memcpy_name) 364 add_implementation(memcpy ${memcpy_name} 365 SRCS ${LIBC_SOURCE_DIR}/src/string/memcpy.cpp 366 HDRS ${LIBC_SOURCE_DIR}/src/string/memcpy.h 367 DEPENDS 368 .memory_utils.memcpy_implementation 369 libc.include.string 370 COMPILE_OPTIONS 371 -fno-builtin-memcpy 372 ${ARGN} 373 ) 374endfunction() 375 376if(${LIBC_TARGET_ARCHITECTURE_IS_X86}) 377 add_memcpy(memcpy_x86_64_opt_sse2 COMPILE_OPTIONS -march=k8 REQUIRE SSE2) 378 add_memcpy(memcpy_x86_64_opt_sse4 COMPILE_OPTIONS -march=nehalem REQUIRE SSE4_2) 379 add_memcpy(memcpy_x86_64_opt_avx2 COMPILE_OPTIONS -march=haswell REQUIRE AVX2) 380 add_memcpy(memcpy_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512F) 381 add_memcpy(memcpy_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 382 add_memcpy(memcpy) 383elseif(${LIBC_TARGET_ARCHITECTURE_IS_AARCH64}) 384 # Disable tail merging as it leads to lower performance. 385 # Note that '-mllvm' needs to be prefixed with 'SHELL:' to prevent CMake flag deduplication. 386 add_memcpy(memcpy_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE} 387 COMPILE_OPTIONS "SHELL:-mllvm --tail-merge-threshold=0") 388 add_memcpy(memcpy COMPILE_OPTIONS "SHELL:-mllvm --tail-merge-threshold=0") 389else() 390 add_memcpy(memcpy_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 391 add_memcpy(memcpy) 392endif() 393 394# ------------------------------------------------------------------------------ 395# memmove 396# ------------------------------------------------------------------------------ 397 398function(add_memmove memmove_name) 399 add_implementation(memmove ${memmove_name} 400 SRCS ${LIBC_SOURCE_DIR}/src/string/memmove.cpp 401 HDRS ${LIBC_SOURCE_DIR}/src/string/memmove.h 402 DEPENDS 403 .memory_utils.memory_utils 404 .memory_utils.memcpy_implementation 405 libc.include.string 406 COMPILE_OPTIONS 407 -fno-builtin 408 ${ARGN} 409 ) 410endfunction() 411 412if(${LIBC_TARGET_ARCHITECTURE_IS_X86}) 413 add_memmove(memmove_x86_64_opt_sse2 COMPILE_OPTIONS -march=k8 REQUIRE SSE2) 414 add_memmove(memmove_x86_64_opt_sse4 COMPILE_OPTIONS -march=nehalem REQUIRE SSE4_2) 415 add_memmove(memmove_x86_64_opt_avx2 COMPILE_OPTIONS -march=haswell REQUIRE AVX2) 416 add_memmove(memmove_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512F) 417 add_memmove(memmove_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 418 add_memmove(memmove) 419elseif(${LIBC_TARGET_ARCHITECTURE_IS_AARCH64}) 420 # Disable tail merging as it leads to lower performance. 421 # Note that '-mllvm' needs to be prefixed with 'SHELL:' to prevent CMake flag deduplication. 422 add_memmove(memmove_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE} 423 COMPILE_OPTIONS "SHELL:-mllvm --tail-merge-threshold=0") 424 add_memmove(memmove COMPILE_OPTIONS "SHELL:-mllvm --tail-merge-threshold=0") 425else() 426 add_memmove(memmove_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 427 add_memmove(memmove) 428endif() 429 430# ------------------------------------------------------------------------------ 431# memset 432# ------------------------------------------------------------------------------ 433 434function(add_memset memset_name) 435 add_implementation(memset ${memset_name} 436 SRCS ${LIBC_SOURCE_DIR}/src/string/memset.cpp 437 HDRS ${LIBC_SOURCE_DIR}/src/string/memset.h 438 DEPENDS 439 .memory_utils.memset_implementation 440 libc.include.string 441 COMPILE_OPTIONS 442 -fno-builtin-memset 443 ${ARGN} 444 ) 445endfunction() 446 447if(${LIBC_TARGET_ARCHITECTURE_IS_X86}) 448 add_memset(memset_x86_64_opt_sse2 COMPILE_OPTIONS -march=k8 REQUIRE SSE2) 449 add_memset(memset_x86_64_opt_sse4 COMPILE_OPTIONS -march=nehalem REQUIRE SSE4_2) 450 add_memset(memset_x86_64_opt_avx2 COMPILE_OPTIONS -march=haswell REQUIRE AVX2) 451 add_memset(memset_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512F) 452 add_memset(memset_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 453 add_memset(memset) 454elseif(${LIBC_TARGET_ARCHITECTURE_IS_AARCH64}) 455 add_memset(memset_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE} 456 COMPILE_OPTIONS "SHELL:-mllvm --tail-merge-threshold=0") 457 add_memset(memset COMPILE_OPTIONS "SHELL:-mllvm --tail-merge-threshold=0") 458else() 459 add_memset(memset_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 460 add_memset(memset) 461endif() 462