#ifndef PROCESS_CSV #define PROCESS_CSV #include #include // Define feature macros for SIMD support with carryless multiplication // We need both SIMD instructions AND carryless multiplication for the CSV parser #if defined(__AVX2__) && defined(__PCLMUL__) #define HAS_SIMD_CSV 1 #define USE_AVX2 1 #include #include #elif defined(__ARM_NEON) && (defined(__ARM_FEATURE_AES) || defined(__ARM_FEATURE_CRYPTO)) // Note: __ARM_FEATURE_CRYPTO is deprecated; prefer __ARM_FEATURE_AES // We need polynomial multiply (vmull_p64/PMULL) for carryless multiplication // Runtime check: 'pmull' flag in /proc/cpuinfo on Linux // We support both macros for compatibility with older compilers #define HAS_SIMD_CSV 1 #define USE_NEON 1 #include #endif // CSV parsing constants #define COMMA_CHAR 0x2C #define NEWLINE_CHAR 0x0A #define QUOTE_CHAR 0x22 #define ALL_ONES_MASK ~0ULL #define ALL_ZEROS_MASK 0ULL // Status codes reported via the `status` out-parameter of // `get_delimiter_indices`. #define GDI_OK 0 #define GDI_UNCLOSED_QUOTE 1 // Sentinel returned by `get_delimiter_indices` when the build lacks // SIMD support or the running CPU does not advertise the carryless // multiply extensions needed by the fast path. The caller falls back // to the Haskell state machine. #define GDI_SIMD_UNAVAILABLE ((size_t)-1) size_t get_delimiter_indices(uint8_t *buf, size_t len, uint8_t separator, size_t *indices, int *status); // Chunked parallel-scan entry points (see process_csv.c). Both return // GDI_SIMD_UNAVAILABLE when the build/CPU lacks SIMD support. size_t count_delimiters_chunk(const uint8_t *buf, size_t base, size_t len, uint8_t separator, int start_in_quote, size_t *newline_count); size_t emit_delimiter_indices_chunk(const uint8_t *buf, size_t base, size_t len, uint8_t separator, int start_in_quote, size_t ordinal_base, size_t *indices, size_t *rowends, size_t *rowend_count); #endif