Skip to content

Commit 0fa7d73

Browse files
tmp
1 parent 6b292c6 commit 0fa7d73

2 files changed

Lines changed: 153 additions & 1 deletion

File tree

.cargo/config.toml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,9 @@ rustflags = ["-g", "-C", "target-cpu=native"]
1010
rustflags = ["-C", "target-feature=+simd128"]
1111

1212
[target.wasm32-wasi]
13-
rustflags = ["-C", "target-feature=+simd128"]
13+
rustflags = ["-C", "target-feature=+simd128"]
14+
15+
[target.aarch64-unknown-linux-gnu]
16+
runner = "qemu-aarch64 -L /usr/aarch64-linux-gnu -cpu max,sve=on"
17+
rustflags = ["-C", "target-feature=+sve2"]
18+
linker = "aarch64-linux-gnu-gcc"

sonic-simd/src/bits.rs

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,3 +100,150 @@ impl BitMask for NeonBits {
100100
Self(self.0 & u64::MAX >> (n * 4))
101101
}
102102
}
103+
104+
#[cfg(target_feature = "sve2")]
105+
#[derive(Debug, Clone, Copy)]
106+
pub struct SveBits(usize);
107+
108+
#[cfg(target_feature = "sve2")]
109+
impl SveBits {
110+
#[inline(always)]
111+
pub fn new(u: usize) -> Self {
112+
Self(u)
113+
}
114+
}
115+
116+
#[cfg(target_feature = "sve2")]
117+
impl BitMask for SveBits {
118+
const LEN: usize = 16;
119+
120+
#[inline(always)]
121+
fn first_offset(&self) -> usize {
122+
self.0
123+
}
124+
125+
#[inline(always)]
126+
fn before(&self, rhs: &Self) -> bool {
127+
self.0 < rhs.0
128+
}
129+
130+
#[inline(always)]
131+
fn all_zero(&self) -> bool {
132+
self.0 == 16
133+
}
134+
135+
#[inline(always)]
136+
fn as_little_endian(&self) -> Self {
137+
*self
138+
}
139+
140+
#[inline(always)]
141+
fn clear_high_bits(&self, n: usize) -> Self {
142+
let nb = 16 - n;
143+
144+
if self.0 >= nb {
145+
Self(16)
146+
} else {
147+
*self
148+
}
149+
}
150+
}
151+
152+
#[cfg(test)]
153+
#[cfg(target_feature = "sve2")]
154+
#[cfg(target_arch = "aarch64")]
155+
mod tests {
156+
use super::*;
157+
158+
#[derive(Debug)]
159+
struct SVEStringBlock {
160+
bs_bits: SveBits,
161+
quote_bits: SveBits,
162+
unescaped_bits: SveBits,
163+
}
164+
165+
impl SVEStringBlock {
166+
#[inline(always)]
167+
pub fn new_sve(ptr: *const u8) -> Self {
168+
let (q, bs, un): (u64, u64, u64);
169+
170+
unsafe {
171+
core::arch::asm!(
172+
"ptrue p0.b, vl16",
173+
"ld1b {{z0.b}}, p0/z, [{ptr}]",
174+
175+
// "
176+
"mov z1.b, #34",
177+
"match p1.b, p0/z, z0.b, z1.b",
178+
"brkb p1.b, p0/z, p1.b",
179+
"cntp {q_idx}, p0, p1.b",
180+
181+
// /
182+
"mov z1.b, #92",
183+
"match p1.b, p0/z, z0.b, z1.b",
184+
"brkb p1.b, p0/z, p1.b",
185+
"cntp {bs_idx}, p0, p1.b",
186+
187+
// ascii control characters
188+
"mov z1.b, #31",
189+
"cmple p1.b, p0/z, z0.b, z1.b",
190+
"brkb p1.b, p0/z, p1.b",
191+
"cntp {un_idx}, p0, p1.b",
192+
193+
ptr = in(reg) ptr,
194+
q_idx = out(reg) q,
195+
bs_idx = out(reg) bs,
196+
un_idx = out(reg) un,
197+
out("z0") _, out("z1") _,
198+
out("p0") _, out("p1") _,
199+
);
200+
}
201+
202+
Self {
203+
quote_bits: SveBits::new(q as usize),
204+
bs_bits: SveBits::new(bs as usize),
205+
unescaped_bits: SveBits::new(un as usize),
206+
}
207+
}
208+
}
209+
210+
impl SVEStringBlock {
211+
#[inline(always)]
212+
pub fn has_unescaped(&self) -> bool {
213+
self.unescaped_bits.0 < self.quote_bits.0
214+
}
215+
216+
#[inline(always)]
217+
pub fn has_quote_first(&self) -> bool {
218+
self.quote_bits.0 < self.bs_bits.0 && !self.has_unescaped()
219+
}
220+
221+
#[inline(always)]
222+
pub fn has_backslash(&self) -> bool {
223+
self.bs_bits.0 < self.quote_bits.0
224+
}
225+
226+
#[inline(always)]
227+
pub fn quote_index(&self) -> usize {
228+
self.quote_bits.0
229+
}
230+
}
231+
232+
#[test]
233+
fn test_sve_bits() {
234+
let s = b"\"\\\t\n";
235+
let block = SVEStringBlock::new_sve(s.as_ptr());
236+
assert_eq!(block.quote_bits.0, 0);
237+
assert_eq!(block.bs_bits.0, 1);
238+
assert_eq!(block.unescaped_bits.0, 2);
239+
240+
let block = SVEStringBlock::new_sve(unsafe {
241+
{
242+
s.as_ptr().add(2)
243+
}
244+
});
245+
assert_eq!(block.quote_bits.0, 16);
246+
assert_eq!(block.bs_bits.0, 16);
247+
assert_eq!(block.unescaped_bits.0, 0);
248+
}
249+
}

0 commit comments

Comments
 (0)