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, ProgramCounter, RegisterFile};
6use ab_riscv_primitives::prelude::*;
7use core::fmt;
8
9#[doc(hidden)]
14pub fn apply_vsetvl<Reg, Regs, ExtState, Memory, PC, CustomError>(
15 regs: &mut Regs,
16 ext_state: &mut ExtState,
17 program_counter: &PC,
18 rd: Reg,
19 rs1: Reg,
20 rs1_value: Reg::Type,
21 vtype_raw: Reg::Type,
22) -> Result<(), ExecutionError<Reg::Type, CustomError>>
23where
24 Reg: Register,
25 Regs: RegisterFile<Reg>,
26 ExtState: VectorRegistersExt<Reg, CustomError>,
27 [(); ExtState::ELEN as usize]:,
28 [(); ExtState::VLEN as usize]:,
29 PC: ProgramCounter<Reg::Type, Memory, CustomError>,
30 CustomError: fmt::Debug,
31{
32 if !ext_state.vector_instructions_allowed() {
34 return Err(ExecutionError::IllegalInstruction {
35 address: program_counter.old_pc(INSTRUCTION_SIZE),
36 });
37 }
38
39 let Some(new_vtype) = Vtype::from_raw::<Reg>(vtype_raw) else {
40 ext_state.set_vtype(None);
41 ext_state.set_vl(0);
42 regs.write(rd, Reg::Type::from(0u8));
43 ext_state.mark_vs_dirty();
44 ext_state.reset_vstart();
45
46 return Ok(());
47 };
48
49 let vlmax = ext_state.vlmax_for_vtype(new_vtype);
50
51 let rs1_is_zero = rs1 == Reg::ZERO;
52 let rd_is_zero = rd == Reg::ZERO;
53
54 let new_vl = if !rs1_is_zero {
55 let avl = rs1_value.as_u64() as u32;
57 ext_state.compute_vl(avl, vlmax)
58 } else if !rd_is_zero {
59 vlmax
61 } else {
62 let current_vl = ext_state.vl();
66 let old_vtype = ext_state.vtype();
67 let old_vlmax = old_vtype.map_or_default(|old_vtype| ext_state.vlmax_for_vtype(old_vtype));
68
69 if vlmax != old_vlmax {
70 ext_state.set_vtype(None);
71 ext_state.set_vl(0);
72 ext_state.mark_vs_dirty();
73 ext_state.reset_vstart();
74
75 return Ok(());
76 }
77
78 ext_state.compute_vl(current_vl, vlmax)
79 };
80
81 ext_state.set_vtype(Some(new_vtype));
82 ext_state.set_vl(new_vl);
83 regs.write(rd, Reg::Type::from(new_vl));
84 ext_state.mark_vs_dirty();
85 ext_state.reset_vstart();
86
87 Ok(())
88}
89
90#[doc(hidden)]
95pub fn apply_vsetivli<Reg, Regs, ExtState, Memory, PC, CustomError>(
96 regs: &mut Regs,
97 ext_state: &mut ExtState,
98 program_counter: &PC,
99 rd: Reg,
100 uimm: u8,
101 vtypei: u16,
102) -> Result<(), ExecutionError<Reg::Type, CustomError>>
103where
104 Reg: Register,
105 Regs: RegisterFile<Reg>,
106 ExtState: VectorRegistersExt<Reg, CustomError>,
107 [(); ExtState::ELEN as usize]:,
108 [(); ExtState::VLEN as usize]:,
109 PC: ProgramCounter<Reg::Type, Memory, CustomError>,
110 CustomError: fmt::Debug,
111{
112 if !ext_state.vector_instructions_allowed() {
114 return Err(ExecutionError::IllegalInstruction {
115 address: program_counter.old_pc(INSTRUCTION_SIZE),
116 });
117 }
118
119 let vtype_raw = Reg::Type::from(vtypei);
120
121 if let Some(new_vtype) = Vtype::from_raw::<Reg>(vtype_raw) {
122 let vlmax = ext_state.vlmax_for_vtype(new_vtype);
123 let avl = u32::from(uimm);
124 let new_vl = ext_state.compute_vl(avl, vlmax);
125
126 ext_state.set_vtype(Some(new_vtype));
127 ext_state.set_vl(new_vl);
128 regs.write(rd, Reg::Type::from(new_vl));
129 } else {
130 ext_state.set_vtype(None);
131 ext_state.set_vl(0);
132 regs.write(rd, Reg::Type::from(0u8));
133 }
134 ext_state.mark_vs_dirty();
135 ext_state.reset_vstart();
136
137 Ok(())
138}