ab_riscv_interpreter/v/zvexx/config/
zvexx_config_helpers.rs1use crate::v::vector_config::VectorConfig;
4use crate::v::vector_registers::VectorRegistersExt;
5use crate::v::zvexx::zvexx_helpers::INSTRUCTION_SIZE;
6use crate::{ExecutionError, PackedAddress, ProgramCounter};
7use ab_riscv_primitives::prelude::*;
8use core::hint::cold_path;
9
10#[inline(always)]
17#[doc(hidden)]
18#[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
19pub const fn apply_vsetvl<Reg, Env, Memory, PC>(
20 env: &mut Env,
21 program_counter: &PC,
22 rd: Reg,
23 rs1: Reg,
24 rs1_value: Reg::Type,
25 vtype_raw: Reg::Type,
26) -> Result<Reg::Type, ExecutionError<Reg::Type>>
27where
28 Reg: [const] Register,
29 Env: [const] VectorRegistersExt<Hart: HartConfig<Reg = Reg>>,
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_vector_config(None);
43 env.mark_vs_dirty();
44 env.reset_vstart();
45
46 return Ok(Reg::Type::from(0u8));
47 };
48
49 let rs1_is_zero = rs1 == Reg::ZERO;
50 let rd_is_zero = rd == Reg::ZERO;
51
52 let new_config = if !rs1_is_zero {
53 let avl = u32::try_from(rs1_value.as_u64()).unwrap_or(u32::MAX);
56 VectorConfig::from_avl(new_vtype, Vl::new_saturating(avl))
57 } else if !rd_is_zero {
58 VectorConfig::from_avl(new_vtype, new_vtype.vlmax())
60 } else if let Some(old_config) = env.vector_config()
61 && old_config.vlmax() == new_vtype.vlmax()
62 {
63 VectorConfig::from_avl(new_vtype, old_config.vl().get())
66 } else {
67 cold_path();
70 env.set_vector_config(None);
71 env.mark_vs_dirty();
72 env.reset_vstart();
73
74 return Ok(Reg::Type::from(0u8));
75 };
76
77 env.set_vector_config(Some(new_config));
78 env.mark_vs_dirty();
79 env.reset_vstart();
80
81 Ok(Reg::Type::from(u32::from(new_config.vl().get())))
82}
83
84#[inline(always)]
91#[doc(hidden)]
92#[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
93pub const fn apply_vsetivli<Reg, Env, Memory, PC>(
94 env: &mut Env,
95 program_counter: &PC,
96 uimm: u8,
97 vtypei: u16,
98) -> Result<Reg::Type, ExecutionError<Reg::Type>>
99where
100 Reg: [const] Register,
101 Env: [const] VectorRegistersExt<Hart: HartConfig<Reg = Reg>>,
102 PC: [const] ProgramCounter<Reg::Type, Memory>,
103{
104 if !env.vector_instructions_allowed() {
106 cold_path();
107 return Err(ExecutionError::IllegalInstruction {
108 address: PackedAddress::new(program_counter.old_pc(INSTRUCTION_SIZE)),
109 });
110 }
111
112 let vtype_raw = Reg::Type::from(vtypei);
113
114 let rd_value = if let Some(new_vtype) = Vtype::from_raw::<Reg>(vtype_raw) {
115 let new_config = VectorConfig::from_avl(new_vtype, Vl::from(uimm));
116 env.set_vector_config(Some(new_config));
117 Reg::Type::from(u32::from(new_config.vl().get()))
118 } else {
119 cold_path();
120 env.set_vector_config(None);
121 Reg::Type::from(0u8)
122 };
123 env.mark_vs_dirty();
124 env.reset_vstart();
125
126 Ok(rd_value)
127}