@@ -547,6 +547,13 @@ pub enum OperandConstraint {
547547 FixedReg ( PReg ) ,
548548 /// On defs only: reuse a use's register.
549549 Reuse ( usize ) ,
550+ /// Operand must be in a specific range of registers.
551+ ///
552+ /// The contained `usize` indicates the (exclusive) upper limit of a
553+ /// register range, `n`. An operand with this constraint may allocate a
554+ /// register between `0 ..= n-1`. Due to encoding constraints, `n` must be a
555+ /// power of two and below 2^16.
556+ Limit ( usize ) ,
550557}
551558
552559impl core:: fmt:: Display for OperandConstraint {
@@ -555,8 +562,9 @@ impl core::fmt::Display for OperandConstraint {
555562 Self :: Any => write ! ( f, "any" ) ,
556563 Self :: Reg => write ! ( f, "reg" ) ,
557564 Self :: Stack => write ! ( f, "stack" ) ,
558- Self :: FixedReg ( preg) => write ! ( f, "fixed({})" , preg) ,
559- Self :: Reuse ( idx) => write ! ( f, "reuse({})" , idx) ,
565+ Self :: FixedReg ( preg) => write ! ( f, "fixed({preg})" ) ,
566+ Self :: Reuse ( idx) => write ! ( f, "reuse({idx})" ) ,
567+ Self :: Limit ( max) => write ! ( f, "limit(0..={})" , max - 1 ) ,
560568 }
561569 }
562570}
@@ -631,6 +639,7 @@ pub struct Operand {
631639 /// The constraints are encoded as follows:
632640 /// - 1xxxxxx => FixedReg(preg)
633641 /// - 01xxxxx => Reuse(index)
642+ /// - 001xxxx => Limit(max)
634643 /// - 0000000 => Any
635644 /// - 0000001 => Reg
636645 /// - 0000010 => Stack
@@ -659,6 +668,12 @@ impl Operand {
659668 debug_assert ! ( which <= 0b11111 ) ;
660669 0b0100000 | which as u32
661670 }
671+ OperandConstraint :: Limit ( max) => {
672+ assert ! ( max. is_power_of_two( ) ) ;
673+ let log2 = max. ilog2 ( ) ;
674+ debug_assert ! ( log2 <= 0b1111 ) ;
675+ 0b0010000 | log2 as u32
676+ }
662677 } ;
663678 let class_field = vreg. class ( ) as u8 as u32 ;
664679 let pos_field = pos as u8 as u32 ;
@@ -919,6 +934,8 @@ impl Operand {
919934 OperandConstraint :: FixedReg ( PReg :: new ( constraint_field & 0b0111111 , self . class ( ) ) )
920935 } else if constraint_field & 0b0100000 != 0 {
921936 OperandConstraint :: Reuse ( constraint_field & 0b0011111 )
937+ } else if constraint_field & 0b0010000 != 0 {
938+ OperandConstraint :: Limit ( 1 << ( constraint_field & 0b0001111 ) )
922939 } else {
923940 match constraint_field {
924941 0 => OperandConstraint :: Any ,
0 commit comments