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 strcat 13 SRCS 14 strcat.cpp 15 HDRS 16 strcat.h 17 DEPENDS 18 .strcpy 19 .string_utils 20) 21 22add_entrypoint_object( 23 strcpy 24 SRCS 25 strcpy.cpp 26 HDRS 27 strcpy.h 28 DEPENDS 29 .memcpy 30 .string_utils 31) 32 33add_entrypoint_object( 34 strlen 35 SRCS 36 strlen.cpp 37 HDRS 38 strlen.h 39 DEPENDS 40 libc.include.string 41) 42 43add_entrypoint_object( 44 strcmp 45 SRCS 46 strcmp.cpp 47 HDRS 48 strcmp.h 49) 50 51add_entrypoint_object( 52 strncmp 53 SRCS 54 strncmp.cpp 55 HDRS 56 strncmp.h 57) 58 59add_entrypoint_object( 60 memchr 61 SRCS 62 memchr.cpp 63 HDRS 64 memchr.h 65 DEPENDS 66 .string_utils 67) 68 69add_entrypoint_object( 70 memmove 71 SRCS 72 memmove.cpp 73 HDRS 74 memmove.h 75 DEPENDS 76 libc.src.__support.integer_operations 77 libc.src.string.memcpy 78) 79 80add_entrypoint_object( 81 strchr 82 SRCS 83 strchr.cpp 84 HDRS 85 strchr.h 86) 87 88add_entrypoint_object( 89 strstr 90 SRCS 91 strstr.cpp 92 HDRS 93 strstr.h 94) 95 96add_entrypoint_object( 97 strncpy 98 SRCS 99 strncpy.cpp 100 HDRS 101 strncpy.h 102) 103 104add_entrypoint_object( 105 strnlen 106 SRCS 107 strnlen.cpp 108 HDRS 109 strnlen.h 110 DEPENDS 111 .string_utils 112) 113 114add_entrypoint_object( 115 memrchr 116 SRCS 117 memrchr.cpp 118 HDRS 119 memrchr.h 120) 121 122add_entrypoint_object( 123 strrchr 124 SRCS 125 strrchr.cpp 126 HDRS 127 strrchr.h 128) 129 130add_entrypoint_object( 131 strcspn 132 SRCS 133 strcspn.cpp 134 HDRS 135 strcspn.h 136 DEPENDS 137 .string_utils 138) 139 140add_entrypoint_object( 141 strspn 142 SRCS 143 strspn.cpp 144 HDRS 145 strspn.h 146 DEPENDS 147 libc.utils.CPP.standalone_cpp 148) 149 150add_entrypoint_object( 151 strpbrk 152 SRCS 153 strpbrk.cpp 154 HDRS 155 strpbrk.h 156 DEPENDS 157 .string_utils 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# memcpy 206# ------------------------------------------------------------------------------ 207 208function(add_memcpy memcpy_name) 209 add_implementation(memcpy ${memcpy_name} 210 SRCS ${MEMCPY_SRC} 211 HDRS ${LIBC_SOURCE_DIR}/src/string/memcpy.h 212 DEPENDS 213 .memory_utils.memory_utils 214 libc.include.string 215 COMPILE_OPTIONS 216 -fno-builtin-memcpy 217 ${ARGN} 218 ) 219endfunction() 220 221if(${LIBC_TARGET_ARCHITECTURE_IS_X86}) 222 set(MEMCPY_SRC ${LIBC_SOURCE_DIR}/src/string/x86_64/memcpy.cpp) 223 add_memcpy(memcpy_x86_64_opt_sse2 COMPILE_OPTIONS -march=k8 REQUIRE SSE2) 224 add_memcpy(memcpy_x86_64_opt_sse4 COMPILE_OPTIONS -march=nehalem REQUIRE SSE4_2) 225 add_memcpy(memcpy_x86_64_opt_avx2 COMPILE_OPTIONS -march=haswell REQUIRE AVX2) 226 add_memcpy(memcpy_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512F) 227 add_memcpy(memcpy_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 228 add_memcpy(memcpy) 229elseif(${LIBC_TARGET_ARCHITECTURE_IS_AARCH64}) 230 set(MEMCPY_SRC ${LIBC_SOURCE_DIR}/src/string/aarch64/memcpy.cpp) 231 # Disable tail merging as it leads to lower performance. 232 # Note that '-mllvm' needs to be prefixed with 'SHELL:' to prevent CMake flag deduplication. 233 add_memcpy(memcpy_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE} 234 COMPILE_OPTIONS "SHELL:-mllvm --tail-merge-threshold=0") 235 add_memcpy(memcpy COMPILE_OPTIONS "SHELL:-mllvm --tail-merge-threshold=0") 236else() 237 set(MEMCPY_SRC ${LIBC_SOURCE_DIR}/src/string/memcpy.cpp) 238 add_memcpy(memcpy_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 239 add_memcpy(memcpy) 240endif() 241 242# ------------------------------------------------------------------------------ 243# memset 244# ------------------------------------------------------------------------------ 245 246function(add_memset memset_name) 247 add_implementation(memset ${memset_name} 248 SRCS ${LIBC_SOURCE_DIR}/src/string/memset.cpp 249 HDRS ${LIBC_SOURCE_DIR}/src/string/memset.h 250 DEPENDS 251 .memory_utils.memory_utils 252 libc.include.string 253 COMPILE_OPTIONS 254 -fno-builtin-memset 255 ${ARGN} 256 ) 257endfunction() 258 259if(${LIBC_TARGET_ARCHITECTURE_IS_X86}) 260 add_memset(memset_x86_64_opt_sse2 COMPILE_OPTIONS -march=k8 REQUIRE SSE2) 261 add_memset(memset_x86_64_opt_sse4 COMPILE_OPTIONS -march=nehalem REQUIRE SSE4_2) 262 add_memset(memset_x86_64_opt_avx2 COMPILE_OPTIONS -march=haswell REQUIRE AVX2) 263 add_memset(memset_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512F) 264 add_memset(memset_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 265 add_memset(memset) 266else() 267 add_memset(memset_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 268 add_memset(memset) 269endif() 270 271# ------------------------------------------------------------------------------ 272# bzero 273# ------------------------------------------------------------------------------ 274 275function(add_bzero bzero_name) 276 add_implementation(bzero ${bzero_name} 277 SRCS ${LIBC_SOURCE_DIR}/src/string/bzero.cpp 278 HDRS ${LIBC_SOURCE_DIR}/src/string/bzero.h 279 DEPENDS 280 .memory_utils.memory_utils 281 libc.include.string 282 COMPILE_OPTIONS 283 -fno-builtin-bzero 284 ${ARGN} 285 ) 286endfunction() 287 288if(${LIBC_TARGET_ARCHITECTURE_IS_X86}) 289 add_bzero(bzero_x86_64_opt_sse2 COMPILE_OPTIONS -march=k8 REQUIRE SSE2) 290 add_bzero(bzero_x86_64_opt_sse4 COMPILE_OPTIONS -march=nehalem REQUIRE SSE4_2) 291 add_bzero(bzero_x86_64_opt_avx2 COMPILE_OPTIONS -march=haswell REQUIRE AVX2) 292 add_bzero(bzero_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512F) 293 add_bzero(bzero_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 294 add_bzero(bzero) 295else() 296 add_bzero(bzero_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 297 add_bzero(bzero) 298endif() 299 300# ------------------------------------------------------------------------------ 301# memcmp 302# ------------------------------------------------------------------------------ 303 304function(add_memcmp memcmp_name) 305 add_implementation(memcmp ${memcmp_name} 306 SRCS ${LIBC_MEMCMP_SRC} 307 HDRS ${LIBC_SOURCE_DIR}/src/string/memcmp.h 308 DEPENDS 309 .memory_utils.memory_utils 310 libc.include.string 311 COMPILE_OPTIONS 312 -fno-builtin-memcmp 313 ${ARGN} 314 ) 315endfunction() 316 317if(${LIBC_TARGET_ARCHITECTURE_IS_X86}) 318 set(LIBC_MEMCMP_SRC ${LIBC_SOURCE_DIR}/src/string/memcmp.cpp) 319 add_memcmp(memcmp_x86_64_opt_sse2 COMPILE_OPTIONS -march=k8 REQUIRE SSE2) 320 add_memcmp(memcmp_x86_64_opt_sse4 COMPILE_OPTIONS -march=nehalem REQUIRE SSE4_2) 321 add_memcmp(memcmp_x86_64_opt_avx2 COMPILE_OPTIONS -march=haswell REQUIRE AVX2) 322 add_memcmp(memcmp_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512F) 323 add_memcmp(memcmp_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 324 add_memcmp(memcmp) 325elseif(${LIBC_TARGET_ARCHITECTURE_IS_AARCH64}) 326 set(LIBC_MEMCMP_SRC ${LIBC_SOURCE_DIR}/src/string/aarch64/memcmp.cpp) 327 add_memcmp(memcmp) 328 add_memcmp(memcmp_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 329else() 330 set(LIBC_MEMCMP_SRC ${LIBC_SOURCE_DIR}/src/string/memcmp.cpp) 331 add_memcmp(memcmp_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) 332 add_memcmp(memcmp) 333endif() 334