cranelift_codegen/machinst/
valueregs.rs1use regalloc2::{PReg, VReg};
5
6use super::{RealReg, Reg, VirtualReg, Writable};
7use std::fmt::Debug;
8
9const VALUE_REGS_PARTS: usize = 2;
10
11#[derive(Clone, Copy, Debug, PartialEq, Eq)]
25pub struct ValueRegs<R: Clone + Copy + Debug + PartialEq + Eq + InvalidSentinel> {
26 parts: [R; VALUE_REGS_PARTS],
27}
28
29pub trait InvalidSentinel: Copy + Eq {
31 fn invalid_sentinel() -> Self;
33 fn is_invalid_sentinel(self) -> bool {
35 self == Self::invalid_sentinel()
36 }
37}
38impl InvalidSentinel for Reg {
39 fn invalid_sentinel() -> Self {
40 Reg::from(VReg::invalid())
41 }
42}
43impl InvalidSentinel for VirtualReg {
44 fn invalid_sentinel() -> Self {
45 VirtualReg::from(VReg::invalid())
46 }
47}
48impl InvalidSentinel for RealReg {
49 fn invalid_sentinel() -> Self {
50 RealReg::from(PReg::invalid())
51 }
52}
53impl InvalidSentinel for Writable<Reg> {
54 fn invalid_sentinel() -> Self {
55 Writable::from_reg(Reg::invalid_sentinel())
56 }
57}
58
59impl<R: Clone + Copy + Debug + PartialEq + Eq + InvalidSentinel> ValueRegs<R> {
60 pub fn invalid() -> Self {
62 ValueRegs {
63 parts: [R::invalid_sentinel(); VALUE_REGS_PARTS],
64 }
65 }
66
67 pub fn is_valid(self) -> bool {
69 !self.parts[0].is_invalid_sentinel()
70 }
71 pub fn is_invalid(self) -> bool {
73 self.parts[0].is_invalid_sentinel()
74 }
75
76 pub fn only_reg(self) -> Option<R> {
78 if self.len() == 1 {
79 Some(self.parts[0])
80 } else {
81 None
82 }
83 }
84
85 pub fn regs(&self) -> &[R] {
87 &self.parts[0..self.len()]
88 }
89}
90
91impl<R: Clone + Copy + Debug + PartialEq + Eq + InvalidSentinel> ValueRegs<R> {
92 pub fn one(reg: R) -> Self {
94 ValueRegs {
95 parts: [reg, R::invalid_sentinel()],
96 }
97 }
98 pub fn two(r1: R, r2: R) -> Self {
100 ValueRegs { parts: [r1, r2] }
101 }
102
103 pub fn len(self) -> usize {
105 (self.parts[0] != R::invalid_sentinel()) as usize
107 + (self.parts[1] != R::invalid_sentinel()) as usize
108 }
109
110 pub fn map<NewR, F>(self, f: F) -> ValueRegs<NewR>
112 where
113 NewR: Clone + Copy + Debug + PartialEq + Eq + InvalidSentinel,
114 F: Fn(R) -> NewR,
115 {
116 ValueRegs {
117 parts: [f(self.parts[0]), f(self.parts[1])],
118 }
119 }
120}
121
122#[allow(dead_code)]
124pub(crate) fn writable_value_regs(regs: ValueRegs<Reg>) -> ValueRegs<Writable<Reg>> {
125 regs.map(|r| Writable::from_reg(r))
126}
127
128#[allow(dead_code)]
130pub(crate) fn non_writable_value_regs(regs: ValueRegs<Writable<Reg>>) -> ValueRegs<Reg> {
131 regs.map(|r| r.to_reg())
132}