Fortran · 3217 bytes Raw Blame History
1 module ferp_simd
2 !> SIMD-accelerated scanning functions for FERP
3 !> Uses ARM NEON on Apple Silicon, scalar fallback otherwise
4 use, intrinsic :: iso_c_binding
5 implicit none
6 private
7
8 public :: simd_find_char_ptr, simd_find_char2_ptr, simd_count_char_ptr
9
10 interface
11 function c_simd_find_char(buf, len, start, needle) bind(C, name="simd_find_char")
12 import :: c_ptr, c_int64_t, c_char
13 type(c_ptr), value :: buf
14 integer(c_int64_t), value :: len
15 integer(c_int64_t), value :: start
16 character(c_char), value :: needle
17 integer(c_int64_t) :: c_simd_find_char
18 end function c_simd_find_char
19
20 function c_simd_find_char2(buf, len, start, c1, c2) bind(C, name="simd_find_char2")
21 import :: c_ptr, c_int64_t, c_char
22 type(c_ptr), value :: buf
23 integer(c_int64_t), value :: len
24 integer(c_int64_t), value :: start
25 character(c_char), value :: c1
26 character(c_char), value :: c2
27 integer(c_int64_t) :: c_simd_find_char2
28 end function c_simd_find_char2
29
30 function c_simd_count_char(buf, len, needle) bind(C, name="simd_count_char")
31 import :: c_ptr, c_int64_t, c_char
32 type(c_ptr), value :: buf
33 integer(c_int64_t), value :: len
34 character(c_char), value :: needle
35 integer(c_int64_t) :: c_simd_count_char
36 end function c_simd_count_char
37 end interface
38
39 contains
40
41 function simd_find_char_ptr(buf_ptr, buf_len, start, needle) result(pos)
42 !> Find first occurrence of needle starting at start (0-indexed C style)
43 !> Returns position (0-indexed) or -1 if not found
44 !> For use with mmap'd buffers
45 type(c_ptr), intent(in) :: buf_ptr
46 integer(c_int64_t), intent(in) :: buf_len
47 integer(c_int64_t), intent(in) :: start
48 character(len=1), intent(in) :: needle
49 integer(c_int64_t) :: pos
50
51 character(kind=c_char) :: c_needle
52
53 ! Convert to C char kind explicitly
54 c_needle = char(ichar(needle), kind=c_char)
55 pos = c_simd_find_char(buf_ptr, buf_len, start, c_needle)
56 end function simd_find_char_ptr
57
58 function simd_find_char2_ptr(buf_ptr, buf_len, start, c1, c2) result(pos)
59 !> Find first occurrence of 2-char sequence (0-indexed)
60 !> Returns position (0-indexed) or -1 if not found
61 type(c_ptr), intent(in) :: buf_ptr
62 integer(c_int64_t), intent(in) :: buf_len
63 integer(c_int64_t), intent(in) :: start
64 character(len=1), intent(in) :: c1, c2
65 integer(c_int64_t) :: pos
66
67 character(kind=c_char) :: cc1, cc2
68
69 ! Convert to C char kind explicitly
70 cc1 = char(ichar(c1), kind=c_char)
71 cc2 = char(ichar(c2), kind=c_char)
72 pos = c_simd_find_char2(buf_ptr, buf_len, start, cc1, cc2)
73 end function simd_find_char2_ptr
74
75 function simd_count_char_ptr(buf_ptr, buf_len, needle) result(count)
76 !> Count occurrences of needle in buffer
77 type(c_ptr), intent(in) :: buf_ptr
78 integer(c_int64_t), intent(in) :: buf_len
79 character(len=1), intent(in) :: needle
80 integer(c_int64_t) :: count
81
82 character(kind=c_char) :: c_needle
83
84 ! Convert to C char kind explicitly
85 c_needle = char(ichar(needle), kind=c_char)
86 count = c_simd_count_char(buf_ptr, buf_len, c_needle)
87 end function simd_count_char_ptr
88
89 end module ferp_simd
90