@@ -534,6 +534,13 @@ pub enum OperandConstraint {
534534 FixedReg ( PReg ) ,
535535 /// On defs only: reuse a use's register.
536536 Reuse ( usize ) ,
537+ /// Operand must be in a specific range of registers.
538+ ///
539+ /// The contained `usize` indicates the (exclusive) upper limit of a
540+ /// register range, `n`. An operand with this constraint may allocate a
541+ /// register between `0 ..= n-1`. Due to encoding constraints, `n` must be a
542+ /// power of two and below 2^16.
543+ Limit ( usize ) ,
537544}
538545
539546impl core:: fmt:: Display for OperandConstraint {
@@ -542,8 +549,9 @@ impl core::fmt::Display for OperandConstraint {
542549 Self :: Any => write ! ( f, "any" ) ,
543550 Self :: Reg => write ! ( f, "reg" ) ,
544551 Self :: Stack => write ! ( f, "stack" ) ,
545- Self :: FixedReg ( preg) => write ! ( f, "fixed({})" , preg) ,
546- Self :: Reuse ( idx) => write ! ( f, "reuse({})" , idx) ,
552+ Self :: FixedReg ( preg) => write ! ( f, "fixed({preg})" ) ,
553+ Self :: Reuse ( idx) => write ! ( f, "reuse({idx})" ) ,
554+ Self :: Limit ( max) => write ! ( f, "limit(0..={})" , max - 1 ) ,
547555 }
548556 }
549557}
@@ -618,6 +626,7 @@ pub struct Operand {
618626 /// The constraints are encoded as follows:
619627 /// - 1xxxxxx => FixedReg(preg)
620628 /// - 01xxxxx => Reuse(index)
629+ /// - 001xxxx => Limit(max)
621630 /// - 0000000 => Any
622631 /// - 0000001 => Reg
623632 /// - 0000010 => Stack
@@ -646,6 +655,12 @@ impl Operand {
646655 debug_assert ! ( which <= 0b11111 ) ;
647656 0b0100000 | which as u32
648657 }
658+ OperandConstraint :: Limit ( max) => {
659+ assert ! ( max. is_power_of_two( ) ) ;
660+ let log2 = max. ilog2 ( ) ;
661+ debug_assert ! ( log2 <= 0b1111 ) ;
662+ 0b0010000 | log2 as u32
663+ }
649664 } ;
650665 let class_field = vreg. class ( ) as u8 as u32 ;
651666 let pos_field = pos as u8 as u32 ;
@@ -906,6 +921,8 @@ impl Operand {
906921 OperandConstraint :: FixedReg ( PReg :: new ( constraint_field & 0b0111111 , self . class ( ) ) )
907922 } else if constraint_field & 0b0100000 != 0 {
908923 OperandConstraint :: Reuse ( constraint_field & 0b0011111 )
924+ } else if constraint_field & 0b0010000 != 0 {
925+ OperandConstraint :: Limit ( 1 << ( constraint_field & 0b0001111 ) )
909926 } else {
910927 match constraint_field {
911928 0 => OperandConstraint :: Any ,
0 commit comments