use crate::ast::{NodeMeta, PolydatNode, Port, PortType, RegLanes, Slot, Value};
pub struct RegView {
meta: NodeMeta,
to: RegLanes,
}
impl RegView {
pub fn new(to: PortType) -> Self {
let (name, view) = match to {
PortType::Reg128 => ("__reg_view_raw", RegLanes::Raw),
PortType::RegI8x16 => ("__reg_view_i8x16", RegLanes::I8x16),
PortType::RegI16x8 => ("__reg_view_i16x8", RegLanes::I16x8),
PortType::RegI32x4 => ("__reg_view_i32x4", RegLanes::I32x4),
PortType::RegI64x2 => ("__reg_view_i64x2", RegLanes::I64x2),
PortType::RegF16x8 => ("__reg_view_f16x8", RegLanes::F16x8),
PortType::RegF32x4 => ("__reg_view_f32x4", RegLanes::F32x4),
PortType::RegF64x2 => ("__reg_view_f64x2", RegLanes::F64x2),
other => panic!("RegView::new: {other:?} is not a register PortType"),
};
Self {
meta: NodeMeta {
name: name.into(),
outs: vec![Port::new("output", to)],
ins: vec![Slot::Wire(Port::new("input", PortType::Reg128))],
},
to: view,
}
}
}
impl PolydatNode for RegView {
fn meta(&self) -> &NodeMeta {
&self.meta
}
fn eval(&self, inputs: &[Value], outputs: &mut [Value]) {
outputs[0] = Value::Reg128(inputs[0].as_reg_bits(), self.to);
}
fn compiled_u64(&self) -> Option<polydat::ast::CompiledU64Op> {
Some(Box::new(|inputs: &[u64], outputs: &mut [u64]| {
outputs[0] = inputs[0];
outputs[1] = inputs[1];
}))
}
}
pub fn is_reg_port(t: PortType) -> bool {
matches!(
t,
PortType::Reg128
| PortType::RegI8x16
| PortType::RegI16x8
| PortType::RegI32x4
| PortType::RegI64x2
| PortType::RegF16x8
| PortType::RegF32x4
| PortType::RegF64x2
)
}