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