1add_subdirectory(memory_utils) 2 3add_header_library( 4 string_utils 5 HDRS 6 string_utils.h 7 DEPENDS 8 libc.utils.CPP.standalone_cpp 9) 10 11add_entrypoint_object( 12 memchr 13 SRCS 14 memchr.cpp 15 HDRS 16 memchr.h 17 DEPENDS 18 .string_utils 19) 20 21add_entrypoint_object( 22 memmove 23 SRCS 24 memmove.cpp 25 HDRS 26 memmove.h 27 DEPENDS 28 libc.src.__support.integer_operations 29 libc.src.string.memcpy 30) 31 32add_entrypoint_object( 33 memrchr 34 SRCS 35 memrchr.cpp 36 HDRS 37 memrchr.h 38) 39 40add_entrypoint_object( 41 strcat 42 SRCS 43 strcat.cpp 44 HDRS 45 strcat.h 46 DEPENDS 47 .strcpy 48 .string_utils 49) 50 51add_entrypoint_object( 52 strchr 53 SRCS 54 strchr.cpp 55 HDRS 56 strchr.h 57) 58 59add_entrypoint_object( 60 strcmp 61 SRCS 62 strcmp.cpp 63 HDRS 64 strcmp.h 65) 66 67add_entrypoint_object( 68 strcpy 69 SRCS 70 strcpy.cpp 71 HDRS 72 strcpy.h 73 DEPENDS 74 .memcpy 75 .string_utils 76) 77 78add_entrypoint_object( 79 strcspn 80 SRCS 81 strcspn.cpp 82 HDRS 83 strcspn.h 84 DEPENDS 85 .string_utils 86) 87 88add_entrypoint_object( 89 strlen 90 SRCS 91 strlen.cpp 92 HDRS 93 strlen.h 94 DEPENDS 95 libc.include.string 96) 97 98add_entrypoint_object( 99 strncmp 100 SRCS 101 strncmp.cpp 102 HDRS 103 strncmp.h 104) 105 106add_entrypoint_object( 107 strncpy 108 SRCS 109 strncpy.cpp 110 HDRS 111 strncpy.h 112) 113 114add_entrypoint_object( 115 strnlen 116 SRCS 117 strnlen.cpp 118 HDRS 119 strnlen.h 120 DEPENDS 121 .string_utils 122) 123 124add_entrypoint_object( 125 strpbrk 126 SRCS 127 strpbrk.cpp 128 HDRS 129 strpbrk.h 130 DEPENDS 131 .string_utils 132) 133 134add_entrypoint_object( 135 strrchr 136 SRCS 137 strrchr.cpp 138 HDRS 139 strrchr.h 140) 141 142add_entrypoint_object( 143 strspn 144 SRCS 145 strspn.cpp 146 HDRS 147 strspn.h 148 DEPENDS 149 libc.utils.CPP.standalone_cpp 150) 151 152add_entrypoint_object( 153 strstr 154 SRCS 155 strstr.cpp 156 HDRS 157 strstr.h 158) 159 160add_entrypoint_object( 161 strtok 162 SRCS 163 strtok.cpp 164 HDRS 165 strtok.h 166 DEPENDS 167 .string_utils 168) 169 170add_entrypoint_object( 171 strtok_r 172 SRCS 173 strtok_r.cpp 174 HDRS 175 strtok_r.h 176 DEPENDS 177 .string_utils 178) 179 180# Helper to define a function with multiple implementations 181# - Computes flags to satisfy required/rejected features and arch, 182# - Declares an entry point, 183# - Attach the REQUIRE_CPU_FEATURES property to the target, 184# - Add the fully qualified target to `${name}_implementations` global property for tests. 185function(add_implementation name impl_name) 186 cmake_parse_arguments( 187 "ADD_IMPL" 188 "" # Optional arguments 189 "" # Single value arguments 190 "REQUIRE;SRCS;HDRS;DEPENDS;COMPILE_OPTIONS" # Multi value arguments 191 ${ARGN}) 192 add_entrypoint_object(${impl_name} 193 NAME ${name} 194 SRCS ${ADD_IMPL_SRCS} 195 HDRS ${ADD_IMPL_HDRS} 196 DEPENDS ${ADD_IMPL_DEPENDS} 197 COMPILE_OPTIONS ${ADD_IMPL_COMPILE_OPTIONS} "SHELL:-mllvm -combiner-global-alias-analysis" 198 ) 199 get_fq_target_name(${impl_name} fq_target_name) 200 set_target_properties(${fq_target_name} PROPERTIES REQUIRE_CPU_FEATURES "${ADD_IMPL_REQUIRE}") 201 set_property(GLOBAL APPEND PROPERTY "${name}_implementations" "${fq_target_name}") 202endfunction() 203 204# ------------------------------------------------------------------------------ 205# bcmp 206# ------------------------------------------------------------------------------ 207 208function(add_bcmp bcmp_name) 209 add_implementation(bcmp ${bcmp_name} 210 SRCS ${LIBC_BCMP_SRC} 211 HDRS ${LIBC_SOURCE_DIR}/src/string/bcmp.h 212 DEPENDS 213 .memory_utils.memory_utils 214 libc.include.string 215 COMPILE_OPTIONS 216 -fno-builtin-memcmp 217 -fno-builtin-bcmp 218 ${ARGN} 219 ) 220endfunction() 221 222if(${LIBC_TARGET_ARCHITECTURE_IS_X86}) 223 set(LIBC_BCMP_SRC ${LIBC_SOURCE_DIR}/src/string/bcmp.cpp) 224 add_bcmp(bcmp_x86_64_opt_sse2 COMPILE_OPTIONS -march=k8 REQUIRE SSE2) 225 add_bcmp(bcmp_x86_64_opt_sse4 COMPILE_OPTIONS -march=nehalem REQUIRE SSE4_2) 226 add_bcmp(bcmp_x86_64_opt_avx2 COMPILE_OPTIONS -march=haswell REQUIRE AVX2) 227 add_bcmp(bcmp_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512F) 228 add_bcmp(bcmp_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 229 add_bcmp(bcmp) 230else() 231 set(LIBC_BCMP_SRC ${LIBC_SOURCE_DIR}/src/string/bcmp.cpp) 232 add_bcmp(bcmp_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 233 add_bcmp(bcmp) 234endif() 235 236# ------------------------------------------------------------------------------ 237# bzero 238# ------------------------------------------------------------------------------ 239 240function(add_bzero bzero_name) 241 add_implementation(bzero ${bzero_name} 242 SRCS ${LIBC_SOURCE_DIR}/src/string/bzero.cpp 243 HDRS ${LIBC_SOURCE_DIR}/src/string/bzero.h 244 DEPENDS 245 .memory_utils.memory_utils 246 libc.include.string 247 COMPILE_OPTIONS 248 -fno-builtin-bzero 249 ${ARGN} 250 ) 251endfunction() 252 253if(${LIBC_TARGET_ARCHITECTURE_IS_X86}) 254 add_bzero(bzero_x86_64_opt_sse2 COMPILE_OPTIONS -march=k8 REQUIRE SSE2) 255 add_bzero(bzero_x86_64_opt_sse4 COMPILE_OPTIONS -march=nehalem REQUIRE SSE4_2) 256 add_bzero(bzero_x86_64_opt_avx2 COMPILE_OPTIONS -march=haswell REQUIRE AVX2) 257 add_bzero(bzero_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512F) 258 add_bzero(bzero_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 259 add_bzero(bzero) 260else() 261 add_bzero(bzero_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 262 add_bzero(bzero) 263endif() 264 265# ------------------------------------------------------------------------------ 266# memcmp 267# ------------------------------------------------------------------------------ 268 269function(add_memcmp memcmp_name) 270 add_implementation(memcmp ${memcmp_name} 271 SRCS ${LIBC_MEMCMP_SRC} 272 HDRS ${LIBC_SOURCE_DIR}/src/string/memcmp.h 273 DEPENDS 274 .memory_utils.memory_utils 275 libc.include.string 276 COMPILE_OPTIONS 277 -fno-builtin-memcmp 278 ${ARGN} 279 ) 280endfunction() 281 282if(${LIBC_TARGET_ARCHITECTURE_IS_X86}) 283 set(LIBC_MEMCMP_SRC ${LIBC_SOURCE_DIR}/src/string/memcmp.cpp) 284 add_memcmp(memcmp_x86_64_opt_sse2 COMPILE_OPTIONS -march=k8 REQUIRE SSE2) 285 add_memcmp(memcmp_x86_64_opt_sse4 COMPILE_OPTIONS -march=nehalem REQUIRE SSE4_2) 286 add_memcmp(memcmp_x86_64_opt_avx2 COMPILE_OPTIONS -march=haswell REQUIRE AVX2) 287 add_memcmp(memcmp_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512F) 288 add_memcmp(memcmp_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 289 add_memcmp(memcmp) 290elseif(${LIBC_TARGET_ARCHITECTURE_IS_AARCH64}) 291 set(LIBC_MEMCMP_SRC ${LIBC_SOURCE_DIR}/src/string/aarch64/memcmp.cpp) 292 add_memcmp(memcmp) 293 add_memcmp(memcmp_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 294else() 295 set(LIBC_MEMCMP_SRC ${LIBC_SOURCE_DIR}/src/string/memcmp.cpp) 296 add_memcmp(memcmp_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 297 add_memcmp(memcmp) 298endif() 299 300# ------------------------------------------------------------------------------ 301# memcpy 302# ------------------------------------------------------------------------------ 303 304function(add_memcpy memcpy_name) 305 add_implementation(memcpy ${memcpy_name} 306 SRCS ${MEMCPY_SRC} 307 HDRS ${LIBC_SOURCE_DIR}/src/string/memcpy.h 308 DEPENDS 309 .memory_utils.memory_utils 310 libc.include.string 311 COMPILE_OPTIONS 312 -fno-builtin-memcpy 313 ${ARGN} 314 ) 315endfunction() 316 317if(${LIBC_TARGET_ARCHITECTURE_IS_X86}) 318 set(MEMCPY_SRC ${LIBC_SOURCE_DIR}/src/string/x86_64/memcpy.cpp) 319 add_memcpy(memcpy_x86_64_opt_sse2 COMPILE_OPTIONS -march=k8 REQUIRE SSE2) 320 add_memcpy(memcpy_x86_64_opt_sse4 COMPILE_OPTIONS -march=nehalem REQUIRE SSE4_2) 321 add_memcpy(memcpy_x86_64_opt_avx2 COMPILE_OPTIONS -march=haswell REQUIRE AVX2) 322 add_memcpy(memcpy_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512F) 323 add_memcpy(memcpy_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 324 add_memcpy(memcpy) 325elseif(${LIBC_TARGET_ARCHITECTURE_IS_AARCH64}) 326 set(MEMCPY_SRC ${LIBC_SOURCE_DIR}/src/string/aarch64/memcpy.cpp) 327 # Disable tail merging as it leads to lower performance. 328 # Note that '-mllvm' needs to be prefixed with 'SHELL:' to prevent CMake flag deduplication. 329 add_memcpy(memcpy_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE} 330 COMPILE_OPTIONS "SHELL:-mllvm --tail-merge-threshold=0") 331 add_memcpy(memcpy COMPILE_OPTIONS "SHELL:-mllvm --tail-merge-threshold=0") 332else() 333 set(MEMCPY_SRC ${LIBC_SOURCE_DIR}/src/string/memcpy.cpp) 334 add_memcpy(memcpy_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 335 add_memcpy(memcpy) 336endif() 337 338# ------------------------------------------------------------------------------ 339# memset 340# ------------------------------------------------------------------------------ 341 342function(add_memset memset_name) 343 add_implementation(memset ${memset_name} 344 SRCS ${LIBC_SOURCE_DIR}/src/string/memset.cpp 345 HDRS ${LIBC_SOURCE_DIR}/src/string/memset.h 346 DEPENDS 347 .memory_utils.memory_utils 348 libc.include.string 349 COMPILE_OPTIONS 350 -fno-builtin-memset 351 ${ARGN} 352 ) 353endfunction() 354 355if(${LIBC_TARGET_ARCHITECTURE_IS_X86}) 356 add_memset(memset_x86_64_opt_sse2 COMPILE_OPTIONS -march=k8 REQUIRE SSE2) 357 add_memset(memset_x86_64_opt_sse4 COMPILE_OPTIONS -march=nehalem REQUIRE SSE4_2) 358 add_memset(memset_x86_64_opt_avx2 COMPILE_OPTIONS -march=haswell REQUIRE AVX2) 359 add_memset(memset_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512F) 360 add_memset(memset_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 361 add_memset(memset) 362else() 363 add_memset(memset_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 364 add_memset(memset) 365endif() 366