eeric_core/rv_core/instruction/executor/v/
vnclipu.rs

1use crate::rv_core::instruction::executor::prelude::*;
2
3use super::utils::rounding::Roundoff;
4
5pub fn wv(Opivv { vd, vs1, vs2, vm }: Opivv, v: &mut VectorContext<'_>) {
6    let roundoff_signed = Roundoff::new_signed(v.csr);
7
8    let uint_max = u64::MAX >> (64 - v.vec_engine.sew.bit_length());
9    let sign_mask = u64::MIN << v.vec_engine.sew.bit_length();
10
11    let vec_engine = *v.vec_engine;
12
13    let vreg = izip!(v.get(vs2).iter_eew(), v.get(vs1).iter_eew())
14        .masked_map(v.default_mask(vm), v.get(vd).iter_eew(), |(vs2, vs1)| {
15            let result = roundoff_signed(
16                vs2 as u128,
17                vs1 as u8 & (2 * v.vec_engine.sew.bit_length() as u8 - 1),
18            );
19
20            if sign_mask & result != 0 {
21                v.csr[VXSAT].write(1);
22                uint_max
23            } else {
24                result
25            }
26        })
27        .collect_with_eew(vec_engine.sew);
28
29    v.apply(vd, vreg);
30}
31
32pub fn wx(Opivx { vd, rs1, vs2, vm }: Opivx, v: &mut VectorContext<'_>, x: &IntegerRegisters) {
33    let roundoff_signed = Roundoff::new_signed(v.csr);
34
35    let uint_max = u64::MAX >> (64 - v.vec_engine.sew.bit_length());
36    let sign_mask = u64::MIN << v.vec_engine.sew.bit_length();
37
38    let vec_engine = *v.vec_engine;
39
40    let vreg = v
41        .get(vs2)
42        .iter_eew()
43        .masked_map(v.default_mask(vm), v.get(vd).iter_eew(), |vs2| {
44            let result = roundoff_signed(
45                vs2 as u128,
46                x[rs1] as u8 & (2 * v.vec_engine.sew.bit_length() as u8 - 1),
47            );
48
49            if sign_mask & result != 0 {
50                v.csr[VXSAT].write(1);
51                uint_max
52            } else {
53                result
54            }
55        })
56        .collect_with_eew(vec_engine.sew);
57
58    v.apply(vd, vreg);
59}
60
61pub fn wi(Opivi { vd, imm5, vs2, vm }: Opivi, v: &mut VectorContext<'_>) {
62    let roundoff_signed = Roundoff::new_signed(v.csr);
63
64    let uint_max = u64::MAX >> (64 - v.vec_engine.sew.bit_length());
65    let sign_mask = u64::MIN << v.vec_engine.sew.bit_length();
66
67    let vec_engine = *v.vec_engine;
68
69    let vreg = v
70        .get(vs2)
71        .iter_eew()
72        .masked_map(v.default_mask(vm), v.get(vd).iter_eew(), |vs2| {
73            let result = roundoff_signed(
74                vs2 as u128,
75                imm5 as u8 & (2 * v.vec_engine.sew.bit_length() as u8 - 1),
76            );
77
78            if sign_mask & result != 0 {
79                v.csr[VXSAT].write(1);
80                uint_max
81            } else {
82                result
83            }
84        })
85        .collect_with_eew(vec_engine.sew);
86
87    v.apply(vd, vreg);
88}