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