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