ab_riscv_interpreter/zvbb/zvkb/
zvkb_helpers.rs1use crate::v::vector_registers::VectorRegistersExt;
4pub use crate::v::zvexx::arith::zvexx_arith_helpers::{OpSrc, check_vreg_group_alignment};
5use crate::v::zvexx::arith::zvexx_arith_helpers::{read_element_u64, sew_mask, write_element_u64};
6use crate::v::zvexx::load::zvexx_load_helpers::mask_bit;
7use ab_riscv_primitives::prelude::*;
8use core::fmt;
9
10#[inline(always)]
23#[doc(hidden)]
24#[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
25pub unsafe fn execute_vandn<Reg, ExtState, CustomError>(
26 ext_state: &mut ExtState,
27 vd: VReg,
28 vs2: VReg,
29 src: OpSrc,
30 sew: Vsew,
31 vm: bool,
32) where
33 Reg: Register,
34 ExtState: VectorRegistersExt<Reg, CustomError>,
35 [(); SUPPORTED_ELEN_VLEN::<{ ExtState::ELEN }, { ExtState::VLEN }>]:,
36 CustomError: fmt::Debug,
37{
38 let vl = ext_state.vl();
39 let vstart = ext_state.vstart();
40 for i in vstart.range_to(vl) {
41 if !vm && !mask_bit(ext_state.read_vregs().get(VReg::V0), i) {
42 continue;
43 }
44 let a = unsafe { read_element_u64(ext_state.read_vregs(), vs2, i, sew) };
48 let b = match src {
49 OpSrc::Vreg(vs1_base) => {
50 unsafe { read_element_u64(ext_state.read_vregs(), vs1_base, i, sew) }
53 }
54 OpSrc::Scalar(val) => val,
55 };
56 let result = !b & a;
59 unsafe {
63 write_element_u64(ext_state.write_vregs(), vd, i, sew, result);
64 }
65 }
66 ext_state.mark_vs_dirty();
67 ext_state.reset_vstart();
68}
69
70#[inline(always)]
80#[doc(hidden)]
81#[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
82pub unsafe fn execute_vbrev8<Reg, ExtState, CustomError>(
83 ext_state: &mut ExtState,
84 vd: VReg,
85 vs2: VReg,
86 sew: Vsew,
87 vm: bool,
88) where
89 Reg: Register,
90 ExtState: VectorRegistersExt<Reg, CustomError>,
91 [(); SUPPORTED_ELEN_VLEN::<{ ExtState::ELEN }, { ExtState::VLEN }>]:,
92 CustomError: fmt::Debug,
93{
94 let vl = ext_state.vl();
95 let vstart = ext_state.vstart();
96 let sew_bytes = u32::from(sew.bytes_width());
97 for i in vstart.range_to(vl) {
98 if !vm && !mask_bit(ext_state.read_vregs().get(VReg::V0), i) {
99 continue;
100 }
101 let elem = unsafe { read_element_u64(ext_state.read_vregs(), vs2, i, sew) };
103 let mut bytes = elem.to_le_bytes();
107 for byte in &mut bytes[..sew_bytes as usize] {
108 *byte = byte.reverse_bits();
109 }
110 let result = u64::from_le_bytes(bytes);
111 unsafe {
113 write_element_u64(ext_state.write_vregs(), vd, i, sew, result);
114 }
115 }
116 ext_state.mark_vs_dirty();
117 ext_state.reset_vstart();
118}
119
120#[inline(always)]
129#[doc(hidden)]
130#[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
131pub unsafe fn execute_vrev8<Reg, ExtState, CustomError>(
132 ext_state: &mut ExtState,
133 vd: VReg,
134 vs2: VReg,
135 sew: Vsew,
136 vm: bool,
137) where
138 Reg: Register,
139 ExtState: VectorRegistersExt<Reg, CustomError>,
140 [(); SUPPORTED_ELEN_VLEN::<{ ExtState::ELEN }, { ExtState::VLEN }>]:,
141 CustomError: fmt::Debug,
142{
143 let vl = ext_state.vl();
144 let vstart = ext_state.vstart();
145 let sew_bytes = u32::from(sew.bytes_width());
146 for i in vstart.range_to(vl) {
147 if !vm && !mask_bit(ext_state.read_vregs().get(VReg::V0), i) {
148 continue;
149 }
150 let elem = unsafe { read_element_u64(ext_state.read_vregs(), vs2, i, sew) };
152 let mut bytes = elem.to_le_bytes();
155 bytes[..sew_bytes as usize].reverse();
156 let result = u64::from_le_bytes(bytes);
157 unsafe {
159 write_element_u64(ext_state.write_vregs(), vd, i, sew, result);
160 }
161 }
162 ext_state.mark_vs_dirty();
163 ext_state.reset_vstart();
164}
165
166#[inline(always)]
175#[doc(hidden)]
176#[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
177pub unsafe fn execute_vrol<Reg, ExtState, CustomError>(
178 ext_state: &mut ExtState,
179 vd: VReg,
180 vs2: VReg,
181 src: OpSrc,
182 sew: Vsew,
183 vm: bool,
184) where
185 Reg: Register,
186 ExtState: VectorRegistersExt<Reg, CustomError>,
187 [(); SUPPORTED_ELEN_VLEN::<{ ExtState::ELEN }, { ExtState::VLEN }>]:,
188 CustomError: fmt::Debug,
189{
190 let vl = ext_state.vl();
191 let vstart = ext_state.vstart();
192 let sew_bits = u64::from(sew.bits_width());
193 let mask = sew_mask(sew);
194 for i in vstart.range_to(vl) {
195 if !vm && !mask_bit(ext_state.read_vregs().get(VReg::V0), i) {
196 continue;
197 }
198 let a = unsafe { read_element_u64(ext_state.read_vregs(), vs2, i, sew) };
200 let amount = match src {
201 OpSrc::Vreg(vs1_base) => {
202 unsafe { read_element_u64(ext_state.read_vregs(), vs1_base, i, sew) }
204 }
205 OpSrc::Scalar(val) => val,
206 };
207 let shift = (amount % sew_bits) as u32;
211 let hi = (a << shift) & mask;
212 let lo = a.unbounded_shr(sew_bits as u32 - shift);
213 let result = hi | lo;
214 unsafe {
216 write_element_u64(ext_state.write_vregs(), vd, i, sew, result);
217 }
218 }
219 ext_state.mark_vs_dirty();
220 ext_state.reset_vstart();
221}
222
223#[inline(always)]
234#[doc(hidden)]
235#[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
236pub unsafe fn execute_vror<Reg, ExtState, CustomError>(
237 ext_state: &mut ExtState,
238 vd: VReg,
239 vs2: VReg,
240 src: OpSrc,
241 sew: Vsew,
242 vm: bool,
243) where
244 Reg: Register,
245 ExtState: VectorRegistersExt<Reg, CustomError>,
246 [(); SUPPORTED_ELEN_VLEN::<{ ExtState::ELEN }, { ExtState::VLEN }>]:,
247 CustomError: fmt::Debug,
248{
249 let vl = ext_state.vl();
250 let vstart = ext_state.vstart();
251 let sew_bits = u64::from(sew.bits_width());
252 let mask = sew_mask(sew);
253 for i in vstart.range_to(vl) {
254 if !vm && !mask_bit(ext_state.read_vregs().get(VReg::V0), i) {
255 continue;
256 }
257 let a = unsafe { read_element_u64(ext_state.read_vregs(), vs2, i, sew) };
259 let amount = match src {
260 OpSrc::Vreg(vs1_base) => {
261 unsafe { read_element_u64(ext_state.read_vregs(), vs1_base, i, sew) }
263 }
264 OpSrc::Scalar(val) => val,
265 };
266 let shift = (amount % sew_bits) as u32;
270 let lo = a >> shift;
271 let hi = a.unbounded_shl(sew_bits as u32 - shift) & mask;
272 let result = lo | hi;
273 unsafe {
275 write_element_u64(ext_state.write_vregs(), vd, i, sew, result);
276 }
277 }
278 ext_state.mark_vs_dirty();
279 ext_state.reset_vstart();
280}