ab_riscv_interpreter/v/zvexx/config/
zvexx_config_helpers.rs1use crate::v::vector_registers::VectorRegistersExt;
4use crate::v::zvexx::zvexx_helpers::INSTRUCTION_SIZE;
5use crate::{ExecutionError, PackedAddress, ProgramCounter};
6use ab_riscv_primitives::prelude::*;
7use core::hint::cold_path;
8
9#[inline(always)]
16#[doc(hidden)]
17#[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
18pub const fn apply_vsetvl<Reg, Env, Memory, PC>(
19 env: &mut Env,
20 program_counter: &PC,
21 rd: Reg,
22 rs1: Reg,
23 rs1_value: Reg::Type,
24 vtype_raw: Reg::Type,
25) -> Result<Reg::Type, ExecutionError<Reg::Type>>
26where
27 Reg: [const] Register,
28 Env: [const] VectorRegistersExt<Reg>,
29 [(); SUPPORTED_ELEN_VLEN::<{ Env::ELEN }, { Env::VLEN }>]:,
30 PC: [const] ProgramCounter<Reg::Type, Memory>,
31{
32 if !env.vector_instructions_allowed() {
34 cold_path();
35 return Err(ExecutionError::IllegalInstruction {
36 address: PackedAddress::new(program_counter.old_pc(INSTRUCTION_SIZE)),
37 });
38 }
39
40 let Some(new_vtype) = Vtype::from_raw::<Reg>(vtype_raw) else {
41 cold_path();
42 env.set_vtype(None);
43 env.set_vl(Vl::ZERO);
44 env.mark_vs_dirty();
45 env.reset_vstart();
46
47 return Ok(Reg::Type::from(0u8));
48 };
49
50 let vlmax = env.vlmax_for_vtype(new_vtype);
51
52 let rs1_is_zero = rs1 == Reg::ZERO;
53 let rd_is_zero = rd == Reg::ZERO;
54
55 let new_vl = if !rs1_is_zero {
56 let avl = rs1_value.as_u64() as u32;
58 env.compute_vl(Vl::new_saturating(avl), vlmax)
59 } else if !rd_is_zero {
60 vlmax
62 } else {
63 let current_vl = env.vl();
67 let old_vtype = env.vtype();
68 let old_vlmax = old_vtype.map_or_default(const |old_vtype| env.vlmax_for_vtype(old_vtype));
69
70 if vlmax != old_vlmax {
71 cold_path();
72 env.set_vtype(None);
73 env.set_vl(Vl::ZERO);
74 env.mark_vs_dirty();
75 env.reset_vstart();
76
77 return Ok(Reg::Type::from(0u8));
78 }
79
80 env.compute_vl(current_vl, vlmax)
81 };
82
83 env.set_vtype(Some(new_vtype));
84 env.set_vl(new_vl);
85 env.mark_vs_dirty();
86 env.reset_vstart();
87
88 Ok(Reg::Type::from(u32::from(new_vl)))
89}
90
91#[inline(always)]
98#[doc(hidden)]
99#[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
100pub const fn apply_vsetivli<Reg, Env, Memory, PC>(
101 env: &mut Env,
102 program_counter: &PC,
103 uimm: u8,
104 vtypei: u16,
105) -> Result<Reg::Type, ExecutionError<Reg::Type>>
106where
107 Reg: [const] Register,
108 Env: [const] VectorRegistersExt<Reg>,
109 [(); SUPPORTED_ELEN_VLEN::<{ Env::ELEN }, { Env::VLEN }>]:,
110 PC: [const] ProgramCounter<Reg::Type, Memory>,
111{
112 if !env.vector_instructions_allowed() {
114 cold_path();
115 return Err(ExecutionError::IllegalInstruction {
116 address: PackedAddress::new(program_counter.old_pc(INSTRUCTION_SIZE)),
117 });
118 }
119
120 let vtype_raw = Reg::Type::from(vtypei);
121
122 let rd_value = if let Some(new_vtype) = Vtype::from_raw::<Reg>(vtype_raw) {
123 let vlmax = env.vlmax_for_vtype(new_vtype);
124 let avl = Vl::from(uimm);
125 let new_vl = env.compute_vl(avl, vlmax);
126
127 env.set_vtype(Some(new_vtype));
128 env.set_vl(new_vl);
129 Reg::Type::from(u32::from(new_vl))
130 } else {
131 cold_path();
132 env.set_vtype(None);
133 env.set_vl(Vl::ZERO);
134 Reg::Type::from(0u8)
135 };
136 env.mark_vs_dirty();
137 env.reset_vstart();
138
139 Ok(rd_value)
140}