1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
use crate::ir::{AbiParam, ArgumentLoc};
use crate::isa::{ConstraintKind, OperandConstraint, RegClassIndex, RegInfo, TargetIsa};
use core::fmt;
#[derive(Clone, Copy, Debug)]
pub enum Affinity {
Unassigned,
Stack,
Reg(RegClassIndex),
}
impl Default for Affinity {
fn default() -> Self {
Self::Unassigned
}
}
impl Affinity {
pub fn new(constraint: &OperandConstraint) -> Self {
if constraint.kind == ConstraintKind::Stack {
Self::Stack
} else {
Self::Reg(constraint.regclass.into())
}
}
pub fn abi(arg: &AbiParam, isa: &dyn TargetIsa) -> Self {
match arg.location {
ArgumentLoc::Unassigned => Self::Unassigned,
ArgumentLoc::Reg(_) => Self::Reg(isa.regclass_for_abi_type(arg.value_type).into()),
ArgumentLoc::Stack(_) => Self::Stack,
}
}
pub fn is_unassigned(self) -> bool {
match self {
Self::Unassigned => true,
_ => false,
}
}
pub fn is_reg(self) -> bool {
match self {
Self::Reg(_) => true,
_ => false,
}
}
pub fn is_stack(self) -> bool {
match self {
Self::Stack => true,
_ => false,
}
}
pub fn merge(&mut self, constraint: &OperandConstraint, reginfo: &RegInfo) {
match *self {
Self::Unassigned => *self = Self::new(constraint),
Self::Reg(rc) => {
if constraint.kind != ConstraintKind::Stack && !constraint.regclass.has_subclass(rc)
{
if let Some(subclass) = constraint.regclass.intersect_index(reginfo.rc(rc)) {
*self = Self::Reg(subclass);
}
}
}
Self::Stack => {}
}
}
pub fn display<'a, R: Into<Option<&'a RegInfo>>>(self, regs: R) -> DisplayAffinity<'a> {
DisplayAffinity(self, regs.into())
}
}
pub struct DisplayAffinity<'a>(Affinity, Option<&'a RegInfo>);
impl<'a> fmt::Display for DisplayAffinity<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.0 {
Affinity::Unassigned => write!(f, "unassigned"),
Affinity::Stack => write!(f, "stack"),
Affinity::Reg(rci) => match self.1 {
Some(regs) => write!(f, "{}", regs.rc(rci)),
None => write!(f, "{}", rci),
},
}
}
}