### SSE to NEON Intrinsics Conversion Example Source: https://github.com/dltcollab/sse2neon/blob/master/README.md Demonstrates the conversion of the SSE _mm_rsqrt_ps intrinsic to its NEON equivalent. This example highlights potential differences in floating-point handling, specifically NaN generation for input 0.0, compared to the SSE intrinsic's behavior. ```c __m128 _mm_rsqrt_ps(__m128 in) { float32x4_t out = vrsqrteq_f32(vreinterpretq_f32_m128(in)); out = vmulq_f32( out, vrsqrtsq_f32(vmulq_f32(vreinterpretq_f32_m128(in), out), out)); return vreinterpretq_m128_f32(out); } ``` -------------------------------- ### Vector Initialization Functions Source: https://context7.com/dltcollab/sse2neon/llms.txt Examples of initializing 128-bit SIMD vectors for floats and integers using various set functions. These functions allow for broadcasting, ordered, and zero-initialized vector creation. ```c #include "sse2neon.h" void vector_initialization_examples() { __m128 broadcast = _mm_set1_ps(3.14f); __m128 individual = _mm_set_ps(4.0f, 3.0f, 2.0f, 1.0f); __m128 ordered = _mm_setr_ps(1.0f, 2.0f, 3.0f, 4.0f); __m128 single = _mm_set_ss(5.0f); __m128 zeros = _mm_setzero_ps(); __m128i int_vec = _mm_set_epi32(4, 3, 2, 1); __m128i int_broadcast = _mm_set1_epi32(42); __m128i int_zeros = _mm_setzero_si128(); __m128i i64_vec = _mm_set_epi64x(0xDEADBEEF, 0xCAFEBABE); } ``` -------------------------------- ### C Control Structure Formatting Source: https://github.com/dltcollab/sse2neon/blob/master/CONTRIBUTING.md Provides examples for standard loop and conditional formatting, emphasizing consistent spacing and brace placement. ```c for (unsigned i = 0; i < __arraycount(items); i++) { /* logic here */ } if (a == b) { /* branch 1 */ } else if (a < b) { /* branch 2 */ } else { /* default */ } ``` -------------------------------- ### C Private Implementation Header Example Source: https://github.com/dltcollab/sse2neon/blob/master/CONTRIBUTING.md Illustrates the use of a private implementation header file (e.g., crypto_impl.h) to contain internal structure details, while a public header file (e.g., crypto.h) exposes only the necessary API for external use. ```c #ifndef _CRYPTO_IMPL_H_ #define _CRYPTO_IMPL_H_ #if !defined(__CRYPTO_PRIVATE) #error "only to be used by the crypto modules" #endif #include "crypto.h" typedef struct crypto { crypto_cipher_t cipher; void *key; size_t key_len; ... } ... #endif ``` ```c #ifndef _CRYPTO_H_ #define _CRYPTO_H_ typedef struct crypto crypto_t; crypto_t *crypto_create(crypto_cipher_t); void crypto_destroy(crypto_t *); ... #endif ``` -------------------------------- ### Configure sse2neon for Graphics Applications Source: https://github.com/dltcollab/sse2neon/blob/master/README.md Example of enabling specific precision macros before including the sse2neon header to improve NaN handling and square root accuracy for graphics workloads. ```c #define SSE2NEON_PRECISE_MINMAX 1 #define SSE2NEON_PRECISE_SQRT 1 #include "sse2neon.h" ``` -------------------------------- ### CRC32C Calculation Examples with sse2neon Source: https://context7.com/dltcollab/sse2neon/llms.txt Demonstrates hardware-accelerated CRC32C checksum calculations for various data types (byte, word, dword, qword) and buffers using the sse2neon library. Requires CRC extension support. ```c #include "sse2neon.h" #include void crc32_examples() { uint32_t crc = 0xFFFFFFFF; // Initial CRC value // CRC32 of a single byte uint8_t byte_data = 0x42; crc = _mm_crc32_u8(crc, byte_data); // CRC32 of 16-bit value uint16_t word_data = 0x1234; crc = _mm_crc32_u16(crc, word_data); // CRC32 of 32-bit value uint32_t dword_data = 0xDEADBEEF; crc = _mm_crc32_u32(crc, dword_data); // CRC32 of 64-bit value uint64_t qword_data = 0x123456789ABCDEF0ULL; crc = _mm_crc32_u64(crc, qword_data); // Computing CRC32 of a buffer uint8_t buffer[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; crc = 0xFFFFFFFF; // Process 8 bytes at a time when possible crc = _mm_crc32_u64(crc, *(uint64_t*)buffer); // Final CRC (typically inverted) uint32_t final_crc = ~crc; } ``` -------------------------------- ### Multi-line Comment Example in C Source: https://github.com/dltcollab/sse2neon/blob/master/CONTRIBUTING.md Demonstrates the standard multi-line comment format for the SSE2NEON project. The opening and closing comment characters are on separate lines, with content lines prefixed by a space and an asterisk for alignment. ```c /* * This is a multi-line comment. */ ``` -------------------------------- ### Single-line Comment Example in C Source: https://github.com/dltcollab/sse2neon/blob/master/CONTRIBUTING.md Illustrates the C89 style for single-line comments, typically used for inline explanations. A two-space indentation precedes the comment, which starts with two forward slashes. ```c return (uintptr_t) val; /* return a bitfield */ ``` -------------------------------- ### Compiler Flags for ARM Architectures with sse2neon Source: https://context7.com/dltcollab/sse2neon/llms.txt Provides essential compiler flags for building code with sse2neon on various ARM architectures, including ARMv8-A (AArch64 and AArch32), ARMv7-A, and Windows ARM64. Also includes an example for cross-compilation testing. ```bash # ARMv8-A AArch64 with crypto and CRC extensions clang++ -march=armv8-a+fp+simd+crypto+crc -O2 mycode.cpp -o mycode # ARMv8-A AArch64 without crypto (minimum flags) clang++ -march=armv8-a+simd -O2 mycode.cpp -o mycode # ARMv8-A AArch32 (32-bit ARM with NEON) arm-linux-gnueabihf-gcc -mfpu=neon-fp-armv8 -O2 mycode.c -o mycode # ARMv7-A (32-bit ARM with NEON) arm-linux-gnueabihf-gcc -mfpu=neon -O2 mycode.c -o mycode # MSVC for Windows ARM64 cl /O2 /arch:arm64 mycode.cpp # Apple Silicon (M1/M2) - auto-detects architecture clang++ -O2 mycode.cpp -o mycode # Cross-compilation test with QEMU make CROSS_COMPILE=aarch64-linux-gnu- check ``` -------------------------------- ### Conditional Compilation for SSE2NEON Header Reduction Source: https://github.com/dltcollab/sse2neon/blob/master/README.md Example of using the 'unifdef' tool to create a reduced sse2neon.h header file tailored for a specific target architecture (AArch64). This process removes unused conditional compilation paths, potentially reducing header size and accelerating compilation. ```shell unifdef -DSSE2NEON_ARCH_AARCH64=1 -D__aarch64__=1\ -D__ARM_FEATURE_DIRECTED_ROUNDING=1 -D__ARM_FEATURE_FMA=1\ -D__ARM_FEATURE_CRYPTO=1 -D__ARM_FEATURE_CRC32=1 -U__ARM_FEATURE_FRINT\ sse2neon.h > sse2neon_aarch64.h ``` -------------------------------- ### AES Encryption Operations (C) Source: https://context7.com/dltcollab/sse2neon/llms.txt Provides examples of hardware-accelerated AES encryption and decryption using SSE2Neon intrinsics. This includes single encryption/decryption rounds, the last round operations, inverse MixColumns, and carry-less multiplication for AES-GCM. ```c #include "sse2neon.h" void aes_examples() { // AES state (128-bit block) __m128i state = _mm_set_epi8( 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 ); // Round key __m128i round_key = _mm_set_epi8( 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10 ); // Single AES encryption round __m128i encrypted = _mm_aesenc_si128(state, round_key); // Last AES encryption round (no MixColumns) __m128i enc_last = _mm_aesenclast_si128(state, round_key); // Single AES decryption round __m128i decrypted = _mm_aesdec_si128(encrypted, round_key); // Last AES decryption round __m128i dec_last = _mm_aesdeclast_si128(encrypted, round_key); // Inverse MixColumns transformation __m128i inv_mc = _mm_aesimc_si128(round_key); // Carry-less multiplication (for GCM mode) __m128i a = _mm_set_epi64x(0, 0x123456789ABCDEF0ULL); __m128i b = _mm_set_epi64x(0, 0xFEDCBA9876543210ULL); __m128i clmul = _mm_clmulepi64_si128(a, b, 0x00); // Low * Low } ``` -------------------------------- ### Cross-compile and Test sse2neon Source: https://github.com/dltcollab/sse2neon/blob/master/README.md Instructions for running the test suite on non-ARM hosts using QEMU and cross-compilation toolchains. ```shell # ARMv8-A AArch64 make CROSS_COMPILE=aarch64-linux-gnu- check # ARMv7-A make CROSS_COMPILE=arm-linux-gnueabihf- check # ARMv8-A AArch32 make CROSS_COMPILE=arm-linux-gnueabihf- \ ARCH_CFLAGS="-mcpu=cortex-a32 -mfpu=neon-fp-armv8" check ``` -------------------------------- ### Basic Usage of sse2neon Source: https://context7.com/dltcollab/sse2neon/llms.txt Demonstrates how to replace standard x86 SSE headers with sse2neon.h to enable SIMD operations on ARM platforms. ```c #include "sse2neon.h" int main() { float data[4] = {1.0f, 2.0f, 3.0f, 4.0f}; __m128 vec = _mm_load_ps(data); __m128 doubled = _mm_add_ps(vec, vec); float result[4]; _mm_store_ps(result, doubled); return 0; } ``` -------------------------------- ### Run sse2neon Test Suite Source: https://github.com/dltcollab/sse2neon/blob/master/README.md Commands to execute the built-in test suite using make, including options for enabling specific features or targeting specific CPU architectures. ```shell # Basic test run make check # Enable crypto and CRC features make FEATURE=crypto+crc check # Target specific CPU make ARCH_CFLAGS="-mcpu=cortex-a53 -mfpu=neon-vfpv4" check ``` -------------------------------- ### C Portable Constant and Type Formatting with C99 Macros Source: https://github.com/dltcollab/sse2neon/blob/master/CONTRIBUTING.md Shows the correct way to define and print constants using C99 macros like UINT64_C and PRIu64 for portability, contrasting it with less portable methods. ```c #define SOME_CONSTANT (UINT64_C(1) << 48) printf("val %" PRIu64 "\n", SOME_CONSTANT); ``` -------------------------------- ### C Object Abstraction with Structs and Header Files Source: https://github.com/dltcollab/sse2neon/blob/master/CONTRIBUTING.md Demonstrates how to simulate object abstraction in C using structs defined in source files and exposing only declarations in header files. This enforces information hiding, preventing direct member access outside the source file. ```c #include "obj.h" struct obj { int value; } obj_t *obj_create(void) { return calloc(1, sizeof(obj_t)); } void obj_destroy(obj_t *obj) { free(obj); } ``` ```c #ifndef _OBJ_H_ #define _OBJ_H_ typedef struct obj; obj_t *obj_create(void); void obj_destroy(obj_t *); #endif ``` -------------------------------- ### Configure Precision and Performance Flags Source: https://context7.com/dltcollab/sse2neon/llms.txt Explains how to use compile-time macros to adjust the precision of mathematical operations like min/max, division, and square root. These flags should be defined before including the library header. ```c #define SSE2NEON_PRECISE_MINMAX 1 #define SSE2NEON_PRECISE_DIV 1 #define SSE2NEON_PRECISE_SQRT 1 #include "sse2neon.h" void precision_example() { __m128 with_nan = _mm_set_ps(1.0f, 0.0f/0.0f, 3.0f, 4.0f); __m128 normal = _mm_set_ps(5.0f, 6.0f, 7.0f, 8.0f); __m128 max_result = _mm_max_ps(with_nan, normal); } ``` -------------------------------- ### C Switch Statement with Fallthrough Source: https://github.com/dltcollab/sse2neon/blob/master/CONTRIBUTING.md Demonstrates the correct indentation for switch cases and the requirement for a fallthrough comment. ```c switch (expr) { case A: /* logic */ break; case B: /* fallthrough */ case C: /* logic */ break; } ``` -------------------------------- ### Compiler Configuration Source: https://context7.com/dltcollab/sse2neon/llms.txt Required compiler flags for building projects using sse2neon on various ARM platforms. ```APIDOC ## Compiler Flags and Build Configuration ### Description Configuration settings required to enable NEON and CRC extensions during compilation. ### Platform Flags - **ARMv8-A AArch64 (Crypto/CRC)**: `-march=armv8-a+fp+simd+crypto+crc` - **ARMv8-A AArch64 (Base)**: `-march=armv8-a+simd` - **ARMv8-A AArch32**: `-mfpu=neon-fp-armv8` - **ARMv7-A**: `-mfpu=neon` - **MSVC (ARM64)**: `/arch:arm64` ### Build Example ```bash clang++ -march=armv8-a+fp+simd+crypto+crc -O2 mycode.cpp -o mycode ``` ``` -------------------------------- ### C99 Structure and Array Initialization Source: https://github.com/dltcollab/sse2neon/blob/master/CONTRIBUTING.md Illustrates the use of C99 designated initializers for structures and multi-dimensional arrays, which improves readability and maintainability. ```c static const crypto_ops_t openssl_ops = { .create = openssl_crypto_create, .destroy = openssl_crypto_destroy, .encrypt = openssl_crypto_encrypt, .decrypt = openssl_crypto_decrypt, .hmac = openssl_crypto_hmac, }; static const uint8_t tcp_fsm[TCP_NSTATES][2][TCPFC_COUNT] = { [TCPS_CLOSED] = { [FLOW_FORW] = { [TCPFC_SYN] = TCPS_SYN_SENT, }, }, }; ``` -------------------------------- ### Perform Math Operations in C Source: https://context7.com/dltcollab/sse2neon/llms.txt Demonstrates mathematical operations on SIMD vectors including min/max, reciprocal approximations, square roots, and rounding. These functions provide efficient vectorized arithmetic for floating-point and integer data. ```c #include "sse2neon.h" void math_examples() { __m128 a = _mm_set_ps(4.0f, -3.0f, 2.0f, -1.0f); __m128 b = _mm_set_ps(1.0f, 5.0f, -2.0f, 3.0f); __m128 min_val = _mm_min_ps(a, b); __m128 max_val = _mm_max_ps(a, b); __m128 positive = _mm_set_ps(4.0f, 2.0f, 1.0f, 0.5f); __m128 rcp = _mm_rcp_ps(positive); __m128 sqrt_val = _mm_sqrt_ps(positive); __m128 rsqrt = _mm_rsqrt_ps(positive); __m128 values = _mm_set_ps(3.7f, 2.5f, 1.2f, -0.8f); __m128 floor_val = _mm_floor_ps(values); __m128 ceil_val = _mm_ceil_ps(values); __m128 round_val = _mm_round_ps(values, _MM_FROUND_TO_NEAREST_INT); __m128 trunc_val = _mm_round_ps(values, _MM_FROUND_TO_ZERO); __m128i ia = _mm_set_epi32(10, -5, 20, -15); __m128i ib = _mm_set_epi32(5, 10, -10, 25); __m128i imin = _mm_min_epi32(ia, ib); __m128i imax = _mm_max_epi32(ia, ib); __m128i umin = _mm_min_epu32(_mm_set1_epi32(100), _mm_set1_epi32(200)); __m128i abs_val = _mm_abs_epi32(ia); } ``` -------------------------------- ### Perform Data Type Conversions with SSE2NEON Source: https://context7.com/dltcollab/sse2neon/llms.txt Demonstrates converting between floating-point and integer types, including rounding, truncation, and sign/zero extension. These functions are essential for interoperability between scalar and vector data types. ```c #include "sse2neon.h" void conversion_examples() { __m128 floats = _mm_set_ps(4.7f, -3.2f, 2.5f, -1.8f); __m128i rounded = _mm_cvtps_epi32(floats); __m128i truncated = _mm_cvttps_epi32(floats); __m128i integers = _mm_set_epi32(10, -5, 3, -8); __m128 from_int = _mm_cvtepi32_ps(integers); float first_float = _mm_cvtss_f32(floats); int first_int = _mm_cvtsi128_si32(integers); __m128i bytes = _mm_set_epi8(0,0,0,0, 0,0,0,0, 0,0,0,0, -5,10,-128,127); __m128i extended16 = _mm_cvtepi8_epi16(bytes); __m128d doubles = _mm_set_pd(3.14159, 2.71828); __m128 from_double = _mm_cvtpd_ps(doubles); } ``` -------------------------------- ### Execute Vector Comparison Operations Source: https://context7.com/dltcollab/sse2neon/llms.txt Shows how to perform element-wise comparisons that generate bitmasks, including NaN-aware comparisons and scalar comparisons. It also demonstrates extracting comparison results into an integer mask. ```c #include "sse2neon.h" #include void comparison_examples() { __m128 a = _mm_set_ps(4.0f, 3.0f, 2.0f, 1.0f); __m128 b = _mm_set_ps(3.0f, 3.0f, 3.0f, 3.0f); __m128 eq = _mm_cmpeq_ps(a, b); __m128 lt = _mm_cmplt_ps(a, b); __m128 gt = _mm_cmpgt_ps(a, b); __m128 nan_val = _mm_set_ps(0.0f/0.0f, 1.0f, 2.0f, 3.0f); __m128 ordered = _mm_cmpord_ps(a, nan_val); int is_lt = _mm_comilt_ss(a, b); __m128i ia = _mm_set_epi32(4, 3, 2, 1); __m128i ib = _mm_set_epi32(3, 3, 3, 3); __m128i ieq = _mm_cmpeq_epi32(ia, ib); int mask = _mm_movemask_ps(lt); printf("Comparison mask: %d\n", mask); } ``` -------------------------------- ### C Pointer Declaration and Spacing Source: https://github.com/dltcollab/sse2neon/blob/master/CONTRIBUTING.md Demonstrates the project's standard for pointer declarations, ensuring consistent spacing for const pointers and restricted pointers. ```c const char *name; /* const pointer; '*' with the name and space before it */ conf_t * const cfg; /* pointer to a const data; spaces around 'const' */ const uint8_t * const charmap; /* const pointer and const data */ const void * restrict key; /* const pointer which does not alias */ ``` -------------------------------- ### Load and Store Operations Source: https://context7.com/dltcollab/sse2neon/llms.txt Demonstrates memory operations for loading data into SIMD registers and storing results back to memory, including support for aligned, unaligned, and partial data access. ```c #include "sse2neon.h" #include void load_store_examples() { float aligned_data[4] __attribute__((aligned(16))) = {1.0f, 2.0f, 3.0f, 4.0f}; __m128 loaded = _mm_load_ps(aligned_data); float unaligned_data[4] = {5.0f, 6.0f, 7.0f, 8.0f}; __m128 unaligned = _mm_loadu_ps(unaligned_data); float single_val = 9.0f; __m128 single = _mm_load_ss(&single_val); __m128 broadcast = _mm_load1_ps(&single_val); __m128 reversed = _mm_loadr_ps(aligned_data); float result[4] __attribute__((aligned(16))); _mm_store_ps(result, loaded); _mm_storeu_ps(result, unaligned); _mm_store_ss(result, single); int32_t int_data[4] __attribute__((aligned(16))) = {10, 20, 30, 40}; __m128i int_loaded = _mm_load_si128((__m128i*)int_data); _mm_store_si128((__m128i*)int_data, int_loaded); __m128i partial = _mm_loadu_si64(int_data); } ``` -------------------------------- ### Perform Shuffle and Permute Operations in C Source: https://context7.com/dltcollab/sse2neon/llms.txt Demonstrates how to rearrange elements within and between vectors using SSE-style shuffle, move, and unpack intrinsics. These operations are essential for data manipulation in SIMD programming. ```c #include "sse2neon.h" void shuffle_examples() { __m128 a = _mm_set_ps(4.0f, 3.0f, 2.0f, 1.0f); __m128 b = _mm_set_ps(8.0f, 7.0f, 6.0f, 5.0f); __m128 shuffled = _mm_shuffle_ps(a, b, _MM_SHUFFLE(0, 1, 2, 3)); __m128 reversed = _mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 1, 2, 3)); __m128 broadcast_x = _mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)); __m128 swap_pairs = _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 3, 0, 1)); __m128 move_ss = _mm_move_ss(a, b); __m128 movehl = _mm_movehl_ps(a, b); __m128 movelh = _mm_movelh_ps(a, b); __m128 unpacklo = _mm_unpacklo_ps(a, b); __m128 unpackhi = _mm_unpackhi_ps(a, b); __m128i ia = _mm_set_epi32(4, 3, 2, 1); __m128i shuffled_i = _mm_shuffle_epi32(ia, _MM_SHUFFLE(0, 1, 2, 3)); __m128i data = _mm_set_epi8(15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0); __m128i indices = _mm_set_epi8(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15); __m128i byte_shuffled = _mm_shuffle_epi8(data, indices); } ``` -------------------------------- ### Perform Arithmetic Operations on Vectors Source: https://context7.com/dltcollab/sse2neon/llms.txt Demonstrates basic arithmetic operations including addition, subtraction, multiplication, and division for both packed floating-point and integer vectors. It also covers scalar operations and saturating arithmetic for integer types. ```c #include "sse2neon.h" void arithmetic_examples() { __m128 a = _mm_set_ps(4.0f, 3.0f, 2.0f, 1.0f); __m128 b = _mm_set_ps(8.0f, 6.0f, 4.0f, 2.0f); __m128 sum = _mm_add_ps(a, b); __m128 diff = _mm_sub_ps(a, b); __m128 prod = _mm_mul_ps(a, b); __m128 quot = _mm_div_ps(a, b); __m128 sum_ss = _mm_add_ss(a, b); __m128 mul_ss = _mm_mul_ss(a, b); __m128i ia = _mm_set_epi32(4, 3, 2, 1); __m128i ib = _mm_set_epi32(8, 6, 4, 2); __m128i isum = _mm_add_epi32(ia, ib); __m128i idiff = _mm_sub_epi32(ia, ib); __m128i imul = _mm_mullo_epi32(ia, ib); __m128i i16a = _mm_set_epi16(8, 7, 6, 5, 4, 3, 2, 1); __m128i i16b = _mm_set_epi16(1, 1, 1, 1, 1, 1, 1, 1); __m128i i16sum = _mm_add_epi16(i16a, i16b); __m128i sat_add = _mm_adds_epi16(i16a, i16b); __m128i sat_sub = _mm_subs_epu8(_mm_set1_epi8(10), _mm_set1_epi8(20)); } ``` -------------------------------- ### SSE Header Inclusion Replacement Source: https://github.com/dltcollab/sse2neon/blob/master/README.md Illustrates how to replace standard Intel SSE header inclusions with the sse2neon.h header file in C/C++ code. This change enables the use of NEON-based implementations for SSE intrinsics. ```c // Before #include #include // After #include "sse2neon.h" ``` -------------------------------- ### Streaming and Cache Operations (C) Source: https://context7.com/dltcollab/sse2neon/llms.txt Demonstrates non-temporal memory operations and cache control hints using SSE2Neon intrinsics. These functions are useful for optimizing data transfers where data is written once and not read again, or for managing cache behavior. ```c #include "sse2neon.h" void streaming_examples() { float data[4] __attribute__((aligned(16))) = {1.0f, 2.0f, 3.0f, 4.0f}; float dest[4] __attribute__((aligned(16))); // Non-temporal (streaming) store - bypasses cache for write-only data __m128 vec = _mm_load_ps(data); _mm_stream_ps(dest, vec); // Integer streaming store __m128i ivec = _mm_set_epi32(4, 3, 2, 1); _mm_stream_si128((__m128i*)dest, ivec); // Streaming load (SSE4.1) - hint that data won't be reused __m128i loaded = _mm_stream_load_si128((__m128i*)data); // Memory fence - ensures all prior stores are visible _mm_sfence(); // Store fence _mm_lfence(); // Load fence _mm_mfence(); // Full fence (load + store) // Cache line flush (implementation may be no-op on some ARM platforms) _mm_clflush(data); // Prefetch hint _mm_prefetch((const char*)data, _MM_HINT_T0); // Prefetch to all cache levels _mm_prefetch((const char*)data, _MM_HINT_NTA); // Non-temporal prefetch // Pause instruction (for spin-wait loops) _mm_pause(); // Yield hint to processor } ``` -------------------------------- ### Math Functions Source: https://context7.com/dltcollab/sse2neon/llms.txt Provides mathematical operations including min/max, reciprocal, square root, and rounding for SSE2Neon. ```APIDOC ## Math Functions ### Description Mathematical operations including min/max, reciprocal, square root, and rounding. ### Method N/A (C function examples) ### Endpoint N/A ### Parameters N/A ### Request Example N/A ### Response N/A ## _mm_min_ps ### Description Computes the element-wise minimum of two 32-bit float vectors. ### Method N/A (C function example) ### Endpoint N/A ### Parameters - **a** (__m128) - The first source vector. - **b** (__m128) - The second source vector. ### Request Example ```c __m128 a = _mm_set_ps(4.0f, -3.0f, 2.0f, -1.0f); __m128 b = _mm_set_ps(1.0f, 5.0f, -2.0f, 3.0f); __m128 min_val = _mm_min_ps(a, b); // Result: [-1, -3, -2, 1] ``` ### Response - **min_val** (__m128) - The vector containing the element-wise minimums. ## _mm_max_ps ### Description Computes the element-wise maximum of two 32-bit float vectors. ### Method N/A (C function example) ### Endpoint N/A ### Parameters - **a** (__m128) - The first source vector. - **b** (__m128) - The second source vector. ### Request Example ```c __m128 a = _mm_set_ps(4.0f, -3.0f, 2.0f, -1.0f); __m128 b = _mm_set_ps(1.0f, 5.0f, -2.0f, 3.0f); __m128 max_val = _mm_max_ps(a, b); // Result: [3, 5, 2, 4] ``` ### Response - **max_val** (__m128) - The vector containing the element-wise maximums. ## _mm_rcp_ps ### Description Computes the approximate reciprocal of each element in a 32-bit float vector. ### Method N/A (C function example) ### Endpoint N/A ### Parameters - **a** (__m128) - The source vector. ### Request Example ```c __m128 positive = _mm_set_ps(4.0f, 2.0f, 1.0f, 0.5f); __m128 rcp = _mm_rcp_ps(positive); // Result: ~[0.25, 0.5, 1.0, 2.0] ``` ### Response - **rcp** (__m128) - The vector containing the approximate reciprocals. ## _mm_sqrt_ps ### Description Computes the square root of each element in a 32-bit float vector. ### Method N/A (C function example) ### Endpoint N/A ### Parameters - **a** (__m128) - The source vector. ### Request Example ```c __m128 positive = _mm_set_ps(4.0f, 2.0f, 1.0f, 0.5f); __m128 sqrt_val = _mm_sqrt_ps(positive); // Result: [2.0, 1.414, 1.0, 0.707] ``` ### Response - **sqrt_val** (__m128) - The vector containing the square roots. ## _mm_rsqrt_ps ### Description Computes the approximate reciprocal square root of each element in a 32-bit float vector. ### Method N/A (C function example) ### Endpoint N/A ### Parameters - **a** (__m128) - The source vector. ### Request Example ```c __m128 positive = _mm_set_ps(4.0f, 2.0f, 1.0f, 0.5f); __m128 rsqrt = _mm_rsqrt_ps(positive); // Result: ~[0.5, 0.707, 1.0, 1.414] ``` ### Response - **rsqrt** (__m128) - The vector containing the approximate reciprocal square roots. ## _mm_floor_ps ### Description Computes the floor of each element in a 32-bit float vector (rounds down to the nearest integer). ### Method N/A (C function example) ### Endpoint N/A ### Parameters - **a** (__m128) - The source vector. ### Request Example ```c __m128 values = _mm_set_ps(3.7f, 2.5f, 1.2f, -0.8f); __m128 floor_val = _mm_floor_ps(values); // Result: [3, 2, 1, -1] ``` ### Response - **floor_val** (__m128) - The vector containing the floored values. ## _mm_ceil_ps ### Description Computes the ceiling of each element in a 32-bit float vector (rounds up to the nearest integer). ### Method N/A (C function example) ### Endpoint N/A ### Parameters - **a** (__m128) - The source vector. ### Request Example ```c __m128 values = _mm_set_ps(3.7f, 2.5f, 1.2f, -0.8f); __m128 ceil_val = _mm_ceil_ps(values); // Result: [4, 3, 2, 0] ``` ### Response - **ceil_val** (__m128) - The vector containing the ceiling values. ## _mm_round_ps ### Description Rounds each element in a 32-bit float vector to the nearest integer, with options for different rounding modes. ### Method N/A (C function example) ### Endpoint N/A ### Parameters - **a** (__m128) - The source vector. - **mode** (int) - The rounding mode (e.g., _MM_FROUND_TO_NEAREST_INT, _MM_FROUND_TO_ZERO). ### Request Example ```c __m128 values = _mm_set_ps(3.7f, 2.5f, 1.2f, -0.8f); __m128 round_val = _mm_round_ps(values, _MM_FROUND_TO_NEAREST_INT); // Result: [4, 2, 1, -1] __m128 trunc_val = _mm_round_ps(values, _MM_FROUND_TO_ZERO); // Result: [3, 2, 1, 0] ``` ### Response - **round_val** (__m128) - The vector containing the rounded values. - **trunc_val** (__m128) - The vector containing the truncated values. ## _mm_min_epi32 ### Description Computes the element-wise minimum of two 32-bit signed integer vectors. ### Method N/A (C function example) ### Endpoint N/A ### Parameters - **a** (__m128i) - The first source integer vector. - **b** (__m128i) - The second source integer vector. ### Request Example ```c __m128i ia = _mm_set_epi32(10, -5, 20, -15); __m128i ib = _mm_set_epi32(5, 10, -10, 25); __m128i imin = _mm_min_epi32(ia, ib); // Result: [5, -5, -10, -15] ``` ### Response - **imin** (__m128i) - The vector containing the element-wise minimums. ## _mm_max_epi32 ### Description Computes the element-wise maximum of two 32-bit signed integer vectors. ### Method N/A (C function example) ### Endpoint N/A ### Parameters - **a** (__m128i) - The first source integer vector. - **b** (__m128i) - The second source integer vector. ### Request Example ```c __m128i ia = _mm_set_epi32(10, -5, 20, -15); __m128i ib = _mm_set_epi32(5, 10, -10, 25); __m128i imax = _mm_max_epi32(ia, ib); // Result: [10, 10, 20, 25] ``` ### Response - **imax** (__m128i) - The vector containing the element-wise maximums. ## _mm_min_epu32 ### Description Computes the element-wise minimum of two 32-bit unsigned integer vectors. ### Method N/A (C function example) ### Endpoint N/A ### Parameters - **a** (__m128i) - The first source unsigned integer vector. - **b** (__m128i) - The second source unsigned integer vector. ### Request Example ```c __m128i umin = _mm_min_epu32( _mm_set1_epi32(100), _mm_set1_epi32(200) ); // Result: [100, 100, 100, 100] ``` ### Response - **umin** (__m128i) - The vector containing the element-wise minimums. ## _mm_abs_epi32 ### Description Computes the absolute value of each 32-bit signed integer in a vector. ### Method N/A (C function example) ### Endpoint N/A ### Parameters - **a** (__m128i) - The source integer vector. ### Request Example ```c __m128i ia = _mm_set_epi32(10, -5, 20, -15); __m128i abs_val = _mm_abs_epi32(ia); // Result: [10, 5, 20, 15] ``` ### Response - **abs_val** (__m128i) - The vector containing the absolute values. ``` -------------------------------- ### Implement SSE2NEON Test Function in C++ Source: https://github.com/dltcollab/sse2neon/blob/master/tests/README.md This C++ function demonstrates how to implement a test case for an SSE2NEON intrinsic. It includes placeholders for the C implementation, the Neon intrinsic call, and the result comparison logic. The function is designed to return TEST_SUCCESS, TEST_FAIL, or TEST_UNIMPL based on the comparison. ```cpp result_t test_mm_xxx() { // The C implementation ... // The Neon implementation ret = _mm_xxx(); // Compare the result of two implementations and return either // TEST_SUCCESS, TEST_FAIL, or TEST_UNIMPL ... } ```