@@ -25,7 +25,7 @@ GitHub. See Python Software Foundation License and BSD licenses for these.
2525#include <stdbool.h>
2626#include <stdlib.h>
2727
28- #if defined(__ARM_NEON ) || defined(__ARM_NEON__ )
28+ #if defined(__ARM_NEON ) || defined(__ARM_NEON__ ) || defined( _M_ARM64 )
2929# define PANDAS_HAS_NEON
3030# include <arm_neon.h>
3131#elif defined(__SSE2__ ) || defined(_M_X64 ) || \
@@ -727,6 +727,16 @@ static inline size_t fast_scan_quoted_sse(const char *data, size_t len,
727727
728728#endif
729729
730+ // Unified dispatch macros so call sites don't need to repeat
731+ // NEON-vs-SSE2 #ifdefs.
732+ #ifdef PANDAS_HAS_NEON
733+ # define fast_scan_simd fast_scan_neon
734+ # define fast_scan_quoted_simd fast_scan_quoted_neon
735+ #elif defined(PANDAS_HAS_SSE2 )
736+ # define fast_scan_simd fast_scan_sse
737+ # define fast_scan_quoted_simd fast_scan_quoted_sse
738+ #endif
739+
730740static int tokenize_bytes (parser_t * self , uint64_t line_limit ,
731741 uint64_t start_lines ) {
732742 char * buf = self -> data + self -> datapos ;
@@ -1065,11 +1075,13 @@ static int tokenize_bytes(parser_t *self, uint64_t line_limit,
10651075 // normal character - save in field
10661076 PUSH_CHAR (c );
10671077
1068- #ifdef PANDAS_HAS_NEON
1078+ // SIMD bulk scan: process 16 bytes at a time, copying
1079+ // normal characters directly without state-machine overhead.
1080+ #if defined(PANDAS_HAS_NEON ) || defined(PANDAS_HAS_SSE2 )
10691081 if (!self -> delim_whitespace ) {
10701082 size_t remaining = self -> datalen - (i + 1 );
10711083 if (remaining >= 16 ) {
1072- size_t skip = fast_scan_neon (buf , remaining , vdelim , vterm , vcr ,
1084+ size_t skip = fast_scan_simd (buf , remaining , vdelim , vterm , vcr ,
10731085 vquote , vescape , vcomment );
10741086 if (skip > 0 ) {
10751087 memcpy (stream , buf , skip );
@@ -1080,21 +1092,6 @@ static int tokenize_bytes(parser_t *self, uint64_t line_limit,
10801092 }
10811093 }
10821094 }
1083- #elif defined(PANDAS_HAS_SSE2 )
1084- if (!self -> delim_whitespace ) {
1085- size_t remaining = self -> datalen - (i + 1 );
1086- if (remaining >= 16 ) {
1087- size_t skip = fast_scan_sse (buf , remaining , vdelim , vterm , vcr ,
1088- vquote , vescape , vcomment );
1089- if (skip > 0 ) {
1090- memcpy (stream , buf , skip );
1091- stream += skip ;
1092- slen += skip ;
1093- buf += skip ;
1094- i += skip ;
1095- }
1096- }
1097- }
10981095#endif
10991096 // Scalar bulk scan fallback: copy remaining ordinary characters
11001097 // directly, bypassing the per-char state machine overhead.
@@ -1124,28 +1121,14 @@ static int tokenize_bytes(parser_t *self, uint64_t line_limit,
11241121 // normal character - save in field
11251122 PUSH_CHAR (c );
11261123
1127- // Inside a quoted field, only quote and escape are special.
1128- // Use a lighter SIMD scan that checks fewer characters .
1129- #ifdef PANDAS_HAS_NEON
1124+ // SIMD bulk scan for quoted fields: only quote and escape
1125+ // chars are special, so use a lighter scan .
1126+ #if defined( PANDAS_HAS_NEON ) || defined( PANDAS_HAS_SSE2 )
11301127 {
11311128 size_t remaining = self -> datalen - (i + 1 );
11321129 if (remaining >= 16 ) {
11331130 size_t skip =
1134- fast_scan_quoted_neon (buf , remaining , vquote , vescape );
1135- if (skip > 0 ) {
1136- memcpy (stream , buf , skip );
1137- stream += skip ;
1138- slen += skip ;
1139- buf += skip ;
1140- i += skip ;
1141- }
1142- }
1143- }
1144- #elif defined(PANDAS_HAS_SSE2 )
1145- {
1146- size_t remaining = self -> datalen - (i + 1 );
1147- if (remaining >= 16 ) {
1148- size_t skip = fast_scan_quoted_sse (buf , remaining , vquote , vescape );
1131+ fast_scan_quoted_simd (buf , remaining , vquote , vescape );
11491132 if (skip > 0 ) {
11501133 memcpy (stream , buf , skip );
11511134 stream += skip ;
0 commit comments