1use crate::v::vector_registers::VectorRegistersExt;
4use crate::v::zve64x::arith::zve64x_arith_helpers::{write_element_u64, write_mask_bit};
5use crate::v::zve64x::load::zve64x_load_helpers::{mask_bit, snapshot_mask};
6use crate::{InterpreterState, ProgramCounter, VirtualMemory};
7use ab_riscv_primitives::instructions::v::Vsew;
8use ab_riscv_primitives::registers::general_purpose::Register;
9use ab_riscv_primitives::registers::vector::VReg;
10use core::fmt;
11
12#[inline(always)]
21#[doc(hidden)]
22pub unsafe fn execute_mask_logical_op<Reg, ExtState, Memory, PC, IH, CustomError, F>(
23 state: &mut InterpreterState<Reg, ExtState, Memory, PC, IH, CustomError>,
24 vd: VReg,
25 vs2: VReg,
26 vs1: VReg,
27 op: F,
28) where
29 Reg: Register,
30 [(); Reg::N]:,
31 ExtState: VectorRegistersExt<Reg, CustomError>,
32 [(); ExtState::ELEN as usize]:,
33 [(); ExtState::VLEN as usize]:,
34 [(); ExtState::VLENB as usize]:,
35 Memory: VirtualMemory,
36 PC: ProgramCounter<Reg::Type, Memory, CustomError>,
37 CustomError: fmt::Debug,
38 F: Fn(u8, u8) -> u8,
39{
40 let vs2_snap = *unsafe {
43 state
44 .ext_state
45 .read_vreg()
46 .get_unchecked(usize::from(vs2.bits()))
47 };
48 let vs1_snap = *unsafe {
50 state
51 .ext_state
52 .read_vreg()
53 .get_unchecked(usize::from(vs1.bits()))
54 };
55 let vd_reg = unsafe {
57 state
58 .ext_state
59 .write_vreg()
60 .get_unchecked_mut(usize::from(vd.bits()))
61 };
62 for byte_i in 0..ExtState::VLENB as usize {
63 let a = unsafe { *vs2_snap.get_unchecked(byte_i) };
66 let b = unsafe { *vs1_snap.get_unchecked(byte_i) };
69 *unsafe { vd_reg.get_unchecked_mut(byte_i) } = op(a, b);
72 }
73 state.ext_state.mark_vs_dirty();
74 state.ext_state.reset_vstart();
75}
76
77#[inline(always)]
86#[doc(hidden)]
87pub unsafe fn execute_vcpop<Reg, ExtState, Memory, PC, IH, CustomError>(
88 state: &mut InterpreterState<Reg, ExtState, Memory, PC, IH, CustomError>,
89 rd: Reg,
90 vs2: VReg,
91 vm: bool,
92 vl: u32,
93 vstart: u32,
94) where
95 Reg: Register,
96 [(); Reg::N]:,
97 ExtState: VectorRegistersExt<Reg, CustomError>,
98 [(); ExtState::ELEN as usize]:,
99 [(); ExtState::VLEN as usize]:,
100 [(); ExtState::VLENB as usize]:,
101 Memory: VirtualMemory,
102 PC: ProgramCounter<Reg::Type, Memory, CustomError>,
103 CustomError: fmt::Debug,
104{
105 let mask_buf = unsafe { snapshot_mask(state.ext_state.read_vreg(), vm, vl) };
107 let vs2_reg = *unsafe {
109 state
110 .ext_state
111 .read_vreg()
112 .get_unchecked(usize::from(vs2.bits()))
113 };
114 let mut count = 0u32;
115 for i in vstart..vl {
116 if !mask_bit(&mask_buf, i) {
117 continue;
118 }
119 if mask_bit(&vs2_reg, i) {
120 count += 1;
121 }
122 }
123 state.regs.write(rd, Reg::Type::from(count));
124 state.ext_state.mark_vs_dirty();
125 state.ext_state.reset_vstart();
126}
127
128#[inline(always)]
138#[doc(hidden)]
139pub unsafe fn execute_vfirst<Reg, ExtState, Memory, PC, IH, CustomError>(
140 state: &mut InterpreterState<Reg, ExtState, Memory, PC, IH, CustomError>,
141 rd: Reg,
142 vs2: VReg,
143 vm: bool,
144 vl: u32,
145 vstart: u32,
146) where
147 Reg: Register,
148 [(); Reg::N]:,
149 ExtState: VectorRegistersExt<Reg, CustomError>,
150 [(); ExtState::ELEN as usize]:,
151 [(); ExtState::VLEN as usize]:,
152 [(); ExtState::VLENB as usize]:,
153 Memory: VirtualMemory,
154 PC: ProgramCounter<Reg::Type, Memory, CustomError>,
155 CustomError: fmt::Debug,
156{
157 let mask_buf = unsafe { snapshot_mask(state.ext_state.read_vreg(), vm, vl) };
159 let vs2_reg = *unsafe {
161 state
162 .ext_state
163 .read_vreg()
164 .get_unchecked(usize::from(vs2.bits()))
165 };
166 let not_found = u64::MAX;
168 let mut result = not_found;
169 for i in vstart..vl {
170 if !mask_bit(&mask_buf, i) {
171 continue;
172 }
173 if mask_bit(&vs2_reg, i) {
174 result = u64::from(i);
175 break;
176 }
177 }
178 let reg_value = if result == not_found {
184 !Reg::Type::from(0u8)
185 } else {
186 Reg::Type::from(result as u32)
187 };
188 state.regs.write(rd, reg_value);
189 state.ext_state.mark_vs_dirty();
190 state.ext_state.reset_vstart();
191}
192
193#[inline(always)]
206#[doc(hidden)]
207pub unsafe fn execute_vmsbf<Reg, ExtState, Memory, PC, IH, CustomError>(
208 state: &mut InterpreterState<Reg, ExtState, Memory, PC, IH, CustomError>,
209 vd: VReg,
210 vs2: VReg,
211 vm: bool,
212 vl: u32,
213 vstart: u32,
214) where
215 Reg: Register,
216 [(); Reg::N]:,
217 ExtState: VectorRegistersExt<Reg, CustomError>,
218 [(); ExtState::ELEN as usize]:,
219 [(); ExtState::VLEN as usize]:,
220 [(); ExtState::VLENB as usize]:,
221 Memory: VirtualMemory,
222 PC: ProgramCounter<Reg::Type, Memory, CustomError>,
223 CustomError: fmt::Debug,
224{
225 let mask_buf = unsafe { snapshot_mask(state.ext_state.read_vreg(), vm, vl) };
227 let vs2_snap = *unsafe {
229 state
230 .ext_state
231 .read_vreg()
232 .get_unchecked(usize::from(vs2.bits()))
233 };
234 let mut found_first = false;
235 for i in vstart..vl {
236 if !mask_bit(&mask_buf, i) {
238 continue;
239 }
240 let vs2_bit = mask_bit(&vs2_snap, i);
241 let result = !found_first && !vs2_bit;
243 if vs2_bit {
244 found_first = true;
245 }
246 unsafe { write_mask_bit(state.ext_state.write_vreg(), vd, i, result) };
248 }
249 state.ext_state.mark_vs_dirty();
250 state.ext_state.reset_vstart();
251}
252
253#[inline(always)]
261#[doc(hidden)]
262pub unsafe fn execute_vmsof<Reg, ExtState, Memory, PC, IH, CustomError>(
263 state: &mut InterpreterState<Reg, ExtState, Memory, PC, IH, CustomError>,
264 vd: VReg,
265 vs2: VReg,
266 vm: bool,
267 vl: u32,
268 vstart: u32,
269) where
270 Reg: Register,
271 [(); Reg::N]:,
272 ExtState: VectorRegistersExt<Reg, CustomError>,
273 [(); ExtState::ELEN as usize]:,
274 [(); ExtState::VLEN as usize]:,
275 [(); ExtState::VLENB as usize]:,
276 Memory: VirtualMemory,
277 PC: ProgramCounter<Reg::Type, Memory, CustomError>,
278 CustomError: fmt::Debug,
279{
280 let mask_buf = unsafe { snapshot_mask(state.ext_state.read_vreg(), vm, vl) };
282 let vs2_snap = *unsafe {
284 state
285 .ext_state
286 .read_vreg()
287 .get_unchecked(usize::from(vs2.bits()))
288 };
289 let mut found_first = false;
290 for i in vstart..vl {
291 if !mask_bit(&mask_buf, i) {
292 continue;
293 }
294 let vs2_bit = mask_bit(&vs2_snap, i);
295 let result = !found_first && vs2_bit;
297 if vs2_bit && !found_first {
298 found_first = true;
299 }
300 unsafe { write_mask_bit(state.ext_state.write_vreg(), vd, i, result) };
302 }
303 state.ext_state.mark_vs_dirty();
304 state.ext_state.reset_vstart();
305}
306
307#[inline(always)]
316#[doc(hidden)]
317pub unsafe fn execute_vmsif<Reg, ExtState, Memory, PC, IH, CustomError>(
318 state: &mut InterpreterState<Reg, ExtState, Memory, PC, IH, CustomError>,
319 vd: VReg,
320 vs2: VReg,
321 vm: bool,
322 vl: u32,
323 vstart: u32,
324) where
325 Reg: Register,
326 [(); Reg::N]:,
327 ExtState: VectorRegistersExt<Reg, CustomError>,
328 [(); ExtState::ELEN as usize]:,
329 [(); ExtState::VLEN as usize]:,
330 [(); ExtState::VLENB as usize]:,
331 Memory: VirtualMemory,
332 PC: ProgramCounter<Reg::Type, Memory, CustomError>,
333 CustomError: fmt::Debug,
334{
335 let mask_buf = unsafe { snapshot_mask(state.ext_state.read_vreg(), vm, vl) };
337 let vs2_snap = *unsafe {
339 state
340 .ext_state
341 .read_vreg()
342 .get_unchecked(usize::from(vs2.bits()))
343 };
344 let mut found_first = false;
345 for i in vstart..vl {
346 if !mask_bit(&mask_buf, i) {
347 continue;
348 }
349 let vs2_bit = mask_bit(&vs2_snap, i);
350 let result = !found_first;
352 if vs2_bit {
353 found_first = true;
354 }
355 unsafe { write_mask_bit(state.ext_state.write_vreg(), vd, i, result) };
357 }
358 state.ext_state.mark_vs_dirty();
359 state.ext_state.reset_vstart();
360}
361
362#[inline(always)]
375#[doc(hidden)]
376pub unsafe fn execute_viota<Reg, ExtState, Memory, PC, IH, CustomError>(
377 state: &mut InterpreterState<Reg, ExtState, Memory, PC, IH, CustomError>,
378 vd: VReg,
379 vs2: VReg,
380 vm: bool,
381 vl: u32,
382 vstart: u32,
383 sew: Vsew,
384) where
385 Reg: Register,
386 [(); Reg::N]:,
387 ExtState: VectorRegistersExt<Reg, CustomError>,
388 [(); ExtState::ELEN as usize]:,
389 [(); ExtState::VLEN as usize]:,
390 [(); ExtState::VLENB as usize]:,
391 Memory: VirtualMemory,
392 PC: ProgramCounter<Reg::Type, Memory, CustomError>,
393 CustomError: fmt::Debug,
394{
395 let mask_buf = unsafe { snapshot_mask(state.ext_state.read_vreg(), vm, vl) };
397 let vs2_snap = *unsafe {
399 state
400 .ext_state
401 .read_vreg()
402 .get_unchecked(usize::from(vs2.bits()))
403 };
404 let mut prefix_count = 0;
407 for i in 0..vl {
410 let is_active = mask_bit(&mask_buf, i);
411 if i >= vstart && is_active {
412 unsafe {
414 write_element_u64(
415 state.ext_state.write_vreg(),
416 vd.bits(),
417 i,
418 sew,
419 prefix_count,
420 );
421 }
422 }
423 if mask_bit(&vs2_snap, i) {
426 prefix_count += 1;
427 }
428 }
429 state.ext_state.mark_vs_dirty();
430 state.ext_state.reset_vstart();
431}
432
433#[inline(always)]
444#[doc(hidden)]
445pub unsafe fn execute_vid<Reg, ExtState, Memory, PC, IH, CustomError>(
446 state: &mut InterpreterState<Reg, ExtState, Memory, PC, IH, CustomError>,
447 vd: VReg,
448 vm: bool,
449 vl: u32,
450 vstart: u32,
451 sew: Vsew,
452) where
453 Reg: Register,
454 [(); Reg::N]:,
455 ExtState: VectorRegistersExt<Reg, CustomError>,
456 [(); ExtState::ELEN as usize]:,
457 [(); ExtState::VLEN as usize]:,
458 [(); ExtState::VLENB as usize]:,
459 Memory: VirtualMemory,
460 PC: ProgramCounter<Reg::Type, Memory, CustomError>,
461 CustomError: fmt::Debug,
462{
463 let mask_buf = unsafe { snapshot_mask(state.ext_state.read_vreg(), vm, vl) };
465 for i in vstart..vl {
466 if !mask_bit(&mask_buf, i) {
467 continue;
468 }
469 unsafe {
471 write_element_u64(
472 state.ext_state.write_vreg(),
473 vd.bits(),
474 i,
475 sew,
476 u64::from(i),
477 );
478 }
479 }
480 state.ext_state.mark_vs_dirty();
481 state.ext_state.reset_vstart();
482}