diff --git a/Include/Hallocy/Allocator.h b/Include/Hallocy/Core/Allocator.h similarity index 97% rename from Include/Hallocy/Allocator.h rename to Include/Hallocy/Core/Allocator.h index a8f0805..ed2fc87 100644 --- a/Include/Hallocy/Allocator.h +++ b/Include/Hallocy/Core/Allocator.h @@ -26,7 +26,7 @@ #include #include -#include "Error.h" +#include "../Utils/Error.h" void *hallocy_malloc(size_t size); HallocyError hallocy_free(void *pointer); diff --git a/Include/Hallocy/Error.h b/Include/Hallocy/Utils/Error.h similarity index 100% rename from Include/Hallocy/Error.h rename to Include/Hallocy/Utils/Error.h diff --git a/Include/Hallocy/Utils/Simd.h b/Include/Hallocy/Utils/Simd.h new file mode 100644 index 0000000..3860e58 --- /dev/null +++ b/Include/Hallocy/Utils/Simd.h @@ -0,0 +1,55 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ----------------------------------------------------------------------------- + * File: Simd.h + * Description: + * This file implements the functions for detecting SIMD support and defines the + * enum for specifing the SIMD type. + * + * Author: Mineplay + * ----------------------------------------------------------------------------- + */ +#ifndef HALLOCY_SIMD +#define HALLOCY_SIMD + +#if defined(_MSC_VER) + #if defined(_M_ARM64) + #include + #else + #include + #endif +#else + #if defined(__aarch64__) + #include + #elif defined(__arm__) + #include + #else + #include + #endif +#endif + +typedef enum { + HALLOCY_SIMD_UNDEFINED = 0, + HALLOCY_SIMD_NONE = 1, + HALLOCY_SIMD_SSE = 2, + HALLOCY_SIMD_SSE2 = 3, + HALLOCY_SIMD_AVX = 4, + HALLOCY_SIMD_AVX2 = 5, + HALLOCY_SIMD_AVX512 = 6, + HALLOCY_SIMD_NEON = 7 +} HallocySimdType; + +HallocySimdType hallocy_is_simd_supported(); + +#endif \ No newline at end of file diff --git a/Src/Allocator.c b/Src/Core/Allocator.c similarity index 99% rename from Src/Allocator.c rename to Src/Core/Allocator.c index 5471122..89bd271 100644 --- a/Src/Allocator.c +++ b/Src/Core/Allocator.c @@ -20,7 +20,7 @@ * Author: Mineplay * ----------------------------------------------------------------------------- */ -#include "../Include/Hallocy/Allocator.h" +#include "../../Include/Hallocy/Core/Allocator.h" #if defined(_WIN32) #include diff --git a/Src/Utils/Simd.c b/Src/Utils/Simd.c new file mode 100644 index 0000000..b06de6a --- /dev/null +++ b/Src/Utils/Simd.c @@ -0,0 +1,133 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ----------------------------------------------------------------------------- + * File: Simd.h + * Description: + * This file implements the function for detecting SIMD support. + * + * Author: Mineplay + * ----------------------------------------------------------------------------- + */ +#include "../../Include/Hallocy/Utils/Simd.h" + +static HallocySimdType hallocy_supported_simd = HALLOCY_SIMD_UNDEFINED; + +HallocySimdType hallocy_is_simd_supported() { + if (hallocy_supported_simd != HALLOCY_SIMD_UNDEFINED) { + return hallocy_supported_simd; + } + + #if defined(_MSC_VER) + #if defined(_M_ARM64) + if (isProcessorFeaturePresent(PF_ARM64_SVE)) { + hallocy_supported_simd = HALLOCY_SIMD_NEON; + return hallocy_supported_simd; + } + #else + int cpu_info[4] = { 0 }; + __cpuid(cpu_info, 7); + if ((cpu_info[1] & (1 << 16)) != 0) { + hallocy_supported_simd = HALLOCY_SIMD_AVX512; + return hallocy_supported_simd; + } + + if ((cpu_info[1] & (1 << 5)) != 0) { + hallocy_supported_simd = HALLOCY_SIMD_AVX2; + return hallocy_supported_simd; + } + + __cpuid(cpu_info, 1); + + if ((cpu_info[2] & (1 << 28)) != 0) { + hallocy_supported_simd = HALLOCY_SIMD_AVX; + return hallocy_supported_simd; + } + + if ((cpu_info[3] & (1 << 26)) != 0) { + hallocy_supported_simd = HALLOCY_SIMD_SSE2; + return hallocy_supported_simd; + } + + if ((cpu_info[3] & (1 << 25)) != 0) { + hallocy_supported_simd = HALLOCY_SIMD_SSE2; + return hallocy_supported_simd; + } + #endif + #else + #if defined(__aarch64__) || defined(__arm__) + int file_descriptor = open("/proc/cpuinfo", O_READONLY); + if (file_descriptor == -1) { + return hallocy_supported_simd; + } + + char buffer[256]; + int bytes_read = read(file_descriptor, buffer, sizeof(buffer)); + while (bytes_read > 0) { + for (size_t i = 0; i < bytes_read - 4; i++) { + if (buffer[i] == 'n' && buffer[i + 1] == 'e' && buffer[i + 2] == 'o' && buffer[i + 3] == 'n') { + close(file_descriptor); + + hallocy_supported_simd = HALLOCY_SIMD_NEON; + return hallocy_supported_simd; + } + } + + bytes_read = read(file_descriptor, buffer, sizeof(buffer)); + } + + close(file_descriptor); + #else + unsigned int a, b, c, d; + __asm__ __volatile__ ( + "cpuid" + : "=a" (a), "=b" (b), "=c" (c), "=d" (d) + : "a" (7) + ); + + if ((b & (1 << 16)) != 0) { + hallocy_supported_simd = HALLOCY_SIMD_AVX512; + return hallocy_supported_simd; + } + + if ((b & (1 << 5)) != 0) { + hallocy_supported_simd = HALLOCY_SIMD_AVX2; + return hallocy_supported_simd; + } + + __asm__ __volatile__ ( + "cpuid" + : "=a" (a), "=b" (b), "=c" (c), "=d" (d) + : "a" (1) + ); + + if ((c & (1 << 28)) != 0) { + hallocy_supported_simd = HALLOCY_SIMD_AVX; + return hallocy_supported_simd; + } + + if ((c & (1 << 26)) != 0) { + hallocy_supported_simd = HALLOCY_SIMD_SSE2; + return hallocy_supported_simd; + } + + if ((c & (1 << 25)) != 0) { + hallocy_supported_simd = HALLOCY_SIMD_SSE; + return hallocy_supported_simd; + } + #endif + #endif + + hallocy_supported_simd = HALLOCY_SIMD_NONE; + return hallocy_supported_simd; +} \ No newline at end of file diff --git a/Tests/Main.c b/Tests/Main.c index 3b13990..f345485 100644 --- a/Tests/Main.c +++ b/Tests/Main.c @@ -20,8 +20,9 @@ * ----------------------------------------------------------------------------- */ #include - #include - + #include + #include + int main() { char *memory = (char *)hallocy_malloc(12288); if (memory == NULL) { @@ -40,5 +41,7 @@ return -1; } + printf("Supported simd version: %d\n", hallocy_is_simd_supported()); + return 0; } \ No newline at end of file