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