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, PartialEq, Eq)]
25pub struct ValueRegs<R: Clone + Copy + Debug + PartialEq + Eq + InvalidSentinel> {
26 parts: [R; VALUE_REGS_PARTS],
27}
28
29impl<R: Clone + Copy + Debug + PartialEq + Eq + InvalidSentinel> Debug for ValueRegs<R> {
30 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
31 let mut f = f.debug_tuple("ValueRegs");
32 let mut last_valid = true;
33 for part in self.parts {
34 if part.is_invalid_sentinel() {
35 last_valid = false;
36 } else {
37 debug_assert!(last_valid);
38 f.field(&part);
39 }
40 }
41 f.finish()
42 }
43}
44
45pub trait InvalidSentinel: Copy + Eq {
47 fn invalid_sentinel() -> Self;
49 fn is_invalid_sentinel(self) -> bool {
51 self == Self::invalid_sentinel()
52 }
53}
54impl InvalidSentinel for Reg {
55 fn invalid_sentinel() -> Self {
56 Reg::from(VReg::invalid())
57 }
58}
59impl InvalidSentinel for VirtualReg {
60 fn invalid_sentinel() -> Self {
61 VirtualReg::from(VReg::invalid())
62 }
63}
64impl InvalidSentinel for RealReg {
65 fn invalid_sentinel() -> Self {
66 RealReg::from(PReg::invalid())
67 }
68}
69impl InvalidSentinel for Writable<Reg> {
70 fn invalid_sentinel() -> Self {
71 Writable::from_reg(Reg::invalid_sentinel())
72 }
73}
74
75impl<R: Clone + Copy + Debug + PartialEq + Eq + InvalidSentinel> ValueRegs<R> {
76 pub fn invalid() -> Self {
78 ValueRegs {
79 parts: [R::invalid_sentinel(); VALUE_REGS_PARTS],
80 }
81 }
82
83 pub fn is_valid(self) -> bool {
85 !self.parts[0].is_invalid_sentinel()
86 }
87 pub fn is_invalid(self) -> bool {
89 self.parts[0].is_invalid_sentinel()
90 }
91
92 pub fn only_reg(self) -> Option<R> {
94 if self.len() == 1 {
95 Some(self.parts[0])
96 } else {
97 None
98 }
99 }
100
101 pub fn regs(&self) -> &[R] {
103 &self.parts[0..self.len()]
104 }
105
106 pub fn regs_mut(&mut self) -> &mut [R] {
108 let len = self.len();
109 &mut self.parts[0..len]
110 }
111}
112
113impl<R: Clone + Copy + Debug + PartialEq + Eq + InvalidSentinel> ValueRegs<R> {
114 pub fn one(reg: R) -> Self {
116 ValueRegs {
117 parts: [reg, R::invalid_sentinel()],
118 }
119 }
120 pub fn two(r1: R, r2: R) -> Self {
122 ValueRegs { parts: [r1, r2] }
123 }
124
125 pub fn len(self) -> usize {
127 (self.parts[0] != R::invalid_sentinel()) as usize
129 + (self.parts[1] != R::invalid_sentinel()) as usize
130 }
131
132 pub fn map<NewR, F>(self, f: F) -> ValueRegs<NewR>
134 where
135 NewR: Clone + Copy + Debug + PartialEq + Eq + InvalidSentinel,
136 F: Fn(R) -> NewR,
137 {
138 ValueRegs {
139 parts: [f(self.parts[0]), f(self.parts[1])],
140 }
141 }
142}
143
144#[allow(dead_code)]
146pub(crate) fn writable_value_regs(regs: ValueRegs<Reg>) -> ValueRegs<Writable<Reg>> {
147 regs.map(|r| Writable::from_reg(r))
148}
149
150#[allow(dead_code)]
152pub(crate) fn non_writable_value_regs(regs: ValueRegs<Writable<Reg>>) -> ValueRegs<Reg> {
153 regs.map(|r| r.to_reg())
154}