Skip to main content

polydat_core/library/
register_view.rs

1// Copyright 2024-2026 Jonathan Shook
2// SPDX-License-Identifier: Apache-2.0
3
4//! The register view retags the assembler inserts between register
5//! ports of different lane typings, and the register-port predicate it
6//! keys on (type_system_alignment.md ยง8.4 layer 2).
7//!
8//! A view is a free bitcast: the 128 bits are untouched and only the
9//! lane typing changes. Each view is an ordinary registered node, like
10//! every other entry of the conversion table, so a program can call it
11//! and the conversion fuzzer can reach it by the name the table gives.
12//!
13//! Each takes the raw word: any register view satisfies a register
14//! slot (the free-bitcast rule in `Value::satisfies_slot`).
15
16use crate::ast::{Bits128, PolydatNode, PortType};
17
18/// A register word viewed raw, without a lane typing.
19#[crate::polydat_node(category = Conversions)]
20fn __reg_view_raw(r: Bits128) -> Bits128 {
21    r
22}
23
24/// A register word viewed as sixteen `i8` lanes.
25#[crate::polydat_node(category = Conversions)]
26fn __reg_view_i8x16(r: Bits128) -> [i8; 16] {
27    r.lanes_i8()
28}
29
30/// A register word viewed as eight `i16` lanes.
31#[crate::polydat_node(category = Conversions)]
32fn __reg_view_i16x8(r: Bits128) -> [i16; 8] {
33    r.lanes_i16()
34}
35
36/// A register word viewed as four `i32` lanes.
37#[crate::polydat_node(category = Conversions)]
38fn __reg_view_i32x4(r: Bits128) -> [i32; 4] {
39    r.lanes_i32()
40}
41
42/// A register word viewed as two `i64` lanes.
43#[crate::polydat_node(category = Conversions)]
44fn __reg_view_i64x2(r: Bits128) -> [i64; 2] {
45    r.lanes_i64()
46}
47
48/// A register word viewed as eight `f16` lanes.
49#[crate::polydat_node(category = Conversions)]
50fn __reg_view_f16x8(r: Bits128) -> [half::f16; 8] {
51    r.lanes_f16()
52}
53
54/// A register word viewed as four `f32` lanes.
55#[crate::polydat_node(category = Conversions)]
56fn __reg_view_f32x4(r: Bits128) -> [f32; 4] {
57    r.lanes_f32()
58}
59
60/// A register word viewed as two `f64` lanes.
61#[crate::polydat_node(category = Conversions)]
62fn __reg_view_f64x2(r: Bits128) -> [f64; 2] {
63    r.lanes_f64()
64}
65
66/// The view of a register word as `to`, the retag the assembler
67/// inserts between register ports of different lane typings. `None`
68/// when `to` is not a register type.
69pub fn reg_view(to: PortType) -> Option<Box<dyn PolydatNode>> {
70    Some(match to {
71        PortType::Reg128 => Box::new(RegViewRaw::new()),
72        PortType::RegI8x16 => Box::new(RegViewI8x16::new()),
73        PortType::RegI16x8 => Box::new(RegViewI16x8::new()),
74        PortType::RegI32x4 => Box::new(RegViewI32x4::new()),
75        PortType::RegI64x2 => Box::new(RegViewI64x2::new()),
76        PortType::RegF16x8 => Box::new(RegViewF16x8::new()),
77        PortType::RegF32x4 => Box::new(RegViewF32x4::new()),
78        PortType::RegF64x2 => Box::new(RegViewF64x2::new()),
79        _ => return None,
80    })
81}
82
83/// `true` when `t` is any register-plane PortType.
84pub fn is_reg_port(t: PortType) -> bool {
85    matches!(
86        t,
87        PortType::Reg128
88            | PortType::RegI8x16
89            | PortType::RegI16x8
90            | PortType::RegI32x4
91            | PortType::RegI64x2
92            | PortType::RegF16x8
93            | PortType::RegF32x4
94            | PortType::RegF64x2
95    )
96}