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 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 new_vtype = if let Some(new_vtype) = Vtype::from_raw::<Reg>(vtype_raw) {
40 new_vtype
41 } else {
42 ext_state.set_vtype(None);
43 ext_state.set_vl(0);
44 regs.write(rd, Reg::Type::from(0u8));
45 ext_state.mark_vs_dirty();
46 ext_state.reset_vstart();
47
48 return Ok(());
49 };
50
51 let vlmax = ext_state.vlmax_for_vtype(new_vtype);
52
53 let rs1_is_zero = rs1 == Reg::ZERO;
54 let rd_is_zero = rd == Reg::ZERO;
55
56 let new_vl = if !rs1_is_zero {
57 let avl = rs1_value.as_u64() as u32;
59 ext_state.compute_vl(avl, vlmax)
60 } else if !rd_is_zero {
61 vlmax
63 } else {
64 let current_vl = ext_state.vl();
68 let old_vtype = ext_state.vtype();
69 let old_vlmax = old_vtype.map_or_default(|old_vtype| ext_state.vlmax_for_vtype(old_vtype));
70
71 if vlmax != old_vlmax {
72 ext_state.set_vtype(None);
73 ext_state.set_vl(0);
74 ext_state.mark_vs_dirty();
75 ext_state.reset_vstart();
76
77 return Ok(());
78 }
79
80 ext_state.compute_vl(current_vl, vlmax)
81 };
82
83 ext_state.set_vtype(Some(new_vtype));
84 ext_state.set_vl(new_vl);
85 regs.write(rd, Reg::Type::from(new_vl));
86 ext_state.mark_vs_dirty();
87 ext_state.reset_vstart();
88
89 Ok(())
90}
91
92#[doc(hidden)]
97pub fn apply_vsetivli<Reg, Regs, ExtState, Memory, PC, CustomError>(
98 regs: &mut Regs,
99 ext_state: &mut ExtState,
100 program_counter: &PC,
101 rd: Reg,
102 uimm: u8,
103 vtypei: u16,
104) -> Result<(), ExecutionError<Reg::Type, CustomError>>
105where
106 Reg: Register,
107 Regs: RegisterFile<Reg>,
108 ExtState: VectorRegistersExt<Reg, CustomError>,
109 [(); ExtState::ELEN as usize]:,
110 [(); ExtState::VLEN as usize]:,
111 PC: ProgramCounter<Reg::Type, Memory, CustomError>,
112 CustomError: fmt::Debug,
113{
114 if !ext_state.vector_instructions_allowed() {
116 return Err(ExecutionError::IllegalInstruction {
117 address: program_counter.old_pc(INSTRUCTION_SIZE),
118 });
119 }
120
121 let vtype_raw = Reg::Type::from(vtypei);
122
123 if let Some(new_vtype) = Vtype::from_raw::<Reg>(vtype_raw) {
124 let vlmax = ext_state.vlmax_for_vtype(new_vtype);
125 let avl = u32::from(uimm);
126 let new_vl = ext_state.compute_vl(avl, vlmax);
127
128 ext_state.set_vtype(Some(new_vtype));
129 ext_state.set_vl(new_vl);
130 regs.write(rd, Reg::Type::from(new_vl));
131 } else {
132 ext_state.set_vtype(None);
133 ext_state.set_vl(0);
134 regs.write(rd, Reg::Type::from(0u8));
135 }
136 ext_state.mark_vs_dirty();
137 ext_state.reset_vstart();
138
139 Ok(())
140}