@@ -58,29 +58,36 @@ impl RequirementConflictAt {
5858
5959#[ derive( Clone , Copy , Debug , PartialEq , Eq ) ]
6060pub enum Requirement {
61- FixedReg ( PReg ) ,
62- FixedStack ( PReg ) ,
61+ Any ,
6362 Register ,
63+ FixedReg ( PReg ) ,
64+ Limit ( usize ) ,
6465 Stack ,
65- Any ,
66+ FixedStack ( PReg ) ,
6667}
6768impl Requirement {
6869 #[ inline( always) ]
6970 pub fn merge ( self , other : Requirement ) -> Result < Requirement , RequirementConflict > {
71+ use Requirement :: * ;
72+
7073 match ( self , other) {
71- ( other, Requirement :: Any ) | ( Requirement :: Any , other) => Ok ( other) ,
72- ( Requirement :: Register , Requirement :: Register ) => Ok ( self ) ,
73- ( Requirement :: Stack , Requirement :: Stack ) => Ok ( self ) ,
74- ( Requirement :: Register , Requirement :: FixedReg ( preg) )
75- | ( Requirement :: FixedReg ( preg) , Requirement :: Register ) => {
76- Ok ( Requirement :: FixedReg ( preg) )
77- }
78- ( Requirement :: Stack , Requirement :: FixedStack ( preg) )
79- | ( Requirement :: FixedStack ( preg) , Requirement :: Stack ) => {
80- Ok ( Requirement :: FixedStack ( preg) )
74+ // `Any` matches anything.
75+ ( other, Any ) | ( Any , other) => Ok ( other) ,
76+ // Same kinds match.
77+ ( Register , Register ) => Ok ( self ) ,
78+ ( Stack , Stack ) => Ok ( self ) ,
79+ ( Limit ( a) , Limit ( b) ) => Ok ( Limit ( a. min ( b) ) ) ,
80+ ( FixedReg ( a) , FixedReg ( b) ) if a == b => Ok ( self ) ,
81+ ( FixedStack ( a) , FixedStack ( b) ) if a == b => Ok ( self ) ,
82+ // Limit a 'Register|FixedReg`.
83+ ( Limit ( a) , Register ) | ( Register , Limit ( a) ) => Ok ( Limit ( a) ) ,
84+ ( Limit ( a) , FixedReg ( b) ) | ( FixedReg ( b) , Limit ( a) ) if usize:: from ( a) > b. hw_enc ( ) => {
85+ Ok ( FixedReg ( b) )
8186 }
82- ( Requirement :: FixedReg ( a) , Requirement :: FixedReg ( b) ) if a == b => Ok ( self ) ,
83- ( Requirement :: FixedStack ( a) , Requirement :: FixedStack ( b) ) if a == b => Ok ( self ) ,
87+ // Constrain `Register|Stack` to `Fixed{Reg|Stack}`.
88+ ( Register , FixedReg ( preg) ) | ( FixedReg ( preg) , Register ) => Ok ( FixedReg ( preg) ) ,
89+ ( Stack , FixedStack ( preg) ) | ( FixedStack ( preg) , Stack ) => Ok ( FixedStack ( preg) ) ,
90+ // Fail otherwise.
8491 _ => Err ( RequirementConflict ) ,
8592 }
8693 }
@@ -89,15 +96,15 @@ impl Requirement {
8996 pub fn is_stack ( self ) -> bool {
9097 match self {
9198 Requirement :: Stack | Requirement :: FixedStack ( ..) => true ,
92- Requirement :: Register | Requirement :: FixedReg ( ..) => false ,
99+ Requirement :: Register | Requirement :: FixedReg ( ..) | Requirement :: Limit ( .. ) => false ,
93100 Requirement :: Any => false ,
94101 }
95102 }
96103
97104 #[ inline( always) ]
98105 pub fn is_reg ( self ) -> bool {
99106 match self {
100- Requirement :: Register | Requirement :: FixedReg ( ..) => true ,
107+ Requirement :: Register | Requirement :: FixedReg ( ..) | Requirement :: Limit ( .. ) => true ,
101108 Requirement :: Stack | Requirement :: FixedStack ( ..) => false ,
102109 Requirement :: Any => false ,
103110 }
@@ -116,6 +123,7 @@ impl<'a, F: Function> Env<'a, F> {
116123 }
117124 }
118125 OperandConstraint :: Reg | OperandConstraint :: Reuse ( _) => Requirement :: Register ,
126+ OperandConstraint :: Limit ( max) => Requirement :: Limit ( max) ,
119127 OperandConstraint :: Stack => Requirement :: Stack ,
120128 OperandConstraint :: Any => Requirement :: Any ,
121129 }
0 commit comments