@@ -106,30 +106,41 @@ pub struct PReg {
106106}
107107
108108impl PReg {
109- pub const MAX_BITS : usize = 6 ;
109+ const MAX_BITS : usize = 6 ;
110110 pub const MAX : usize = ( 1 << Self :: MAX_BITS ) - 1 ;
111+ pub const MAX_INT : usize = ( 2 << Self :: MAX_BITS ) - 1 ;
111112 pub const NUM_INDEX : usize = 1 << ( Self :: MAX_BITS + 2 ) ; // including RegClass bits
112113
113114 /// Create a new PReg. The `hw_enc` range is 6 bits.
114115 #[ inline( always) ]
115116 pub const fn new ( hw_enc : usize , class : RegClass ) -> Self {
116- debug_assert ! ( hw_enc <= PReg :: MAX ) ;
117+ match class {
118+ RegClass :: Int => debug_assert ! ( hw_enc <= PReg :: MAX_INT ) ,
119+ RegClass :: Float | RegClass :: Vector => debug_assert ! ( hw_enc <= PReg :: MAX ) ,
120+ }
121+ let mut class = class as u8 ;
122+ if class == 0 && hw_enc > PReg :: MAX {
123+ class = 3 ;
124+ }
117125 PReg {
118- bits : ( ( class as u8 ) << Self :: MAX_BITS ) | ( hw_enc as u8 ) ,
126+ bits : ( class << Self :: MAX_BITS ) | ( ( hw_enc & PReg :: MAX ) as u8 ) ,
119127 }
120128 }
121129
122130 /// The physical register number, as encoded by the ISA for the particular register class.
123131 #[ inline( always) ]
124132 pub const fn hw_enc ( self ) -> usize {
125- self . bits as usize & Self :: MAX
133+ match self . class ( ) {
134+ RegClass :: Int => self . bits as usize & Self :: MAX_INT ,
135+ RegClass :: Float | RegClass :: Vector => self . bits as usize & Self :: MAX ,
136+ }
126137 }
127138
128139 /// The register class.
129140 #[ inline( always) ]
130141 pub const fn class ( self ) -> RegClass {
131142 match ( self . bits >> Self :: MAX_BITS ) & 0b11 {
132- 0 => RegClass :: Int ,
143+ 0 | 3 => RegClass :: Int ,
133144 1 => RegClass :: Float ,
134145 2 => RegClass :: Vector ,
135146 _ => unreachable ! ( ) ,
@@ -156,7 +167,7 @@ impl PReg {
156167 /// data structures.
157168 #[ inline( always) ]
158169 pub const fn invalid ( ) -> Self {
159- PReg :: new ( Self :: MAX , RegClass :: Int )
170+ PReg :: new ( Self :: MAX_INT , RegClass :: Int )
160171 }
161172}
162173
@@ -314,7 +325,7 @@ impl VReg {
314325 pub const fn new ( virt_reg : usize , class : RegClass ) -> Self {
315326 debug_assert ! ( virt_reg <= VReg :: MAX ) ;
316327 VReg {
317- bits : ( ( virt_reg as u32 ) << 2 ) | ( class as u8 as u32 ) ,
328+ bits : ( ( virt_reg as u32 ) << 2 ) | ( class as u32 ) ,
318329 }
319330 }
320331
@@ -540,20 +551,23 @@ impl Operand {
540551 kind : OperandKind ,
541552 pos : OperandPos ,
542553 ) -> Self {
554+ let mut class_field = vreg. class ( ) as u32 ;
543555 let constraint_field = match constraint {
544556 OperandConstraint :: Any => 0 ,
545557 OperandConstraint :: Reg => 1 ,
546558 OperandConstraint :: Stack => 2 ,
547559 OperandConstraint :: FixedReg ( preg) => {
548560 debug_assert_eq ! ( preg. class( ) , vreg. class( ) ) ;
549- 0b1000000 | preg. hw_enc ( ) as u32
561+ if preg. hw_enc ( ) & 0b1000000 != 0 {
562+ class_field = 3 ;
563+ }
564+ 0b1000000 | ( preg. hw_enc ( ) & PReg :: MAX ) as u32
550565 }
551566 OperandConstraint :: Reuse ( which) => {
552567 debug_assert ! ( which <= 31 ) ;
553568 0b0100000 | which as u32
554569 }
555570 } ;
556- let class_field = vreg. class ( ) as u8 as u32 ;
557571 let pos_field = pos as u8 as u32 ;
558572 let kind_field = kind as u8 as u32 ;
559573 Operand {
@@ -748,7 +762,7 @@ impl Operand {
748762 pub fn class ( self ) -> RegClass {
749763 let class_field = ( self . bits >> 21 ) & 3 ;
750764 match class_field {
751- 0 => RegClass :: Int ,
765+ 0 | 3 => RegClass :: Int ,
752766 1 => RegClass :: Float ,
753767 2 => RegClass :: Vector ,
754768 _ => unreachable ! ( ) ,
@@ -785,9 +799,14 @@ impl Operand {
785799 /// its allocation must fulfill.
786800 #[ inline( always) ]
787801 pub fn constraint ( self ) -> OperandConstraint {
802+ let class_field = ( self . bits >> 21 ) as usize & 3 ;
788803 let constraint_field = ( ( self . bits >> 25 ) as usize ) & 127 ;
789804 if constraint_field & 0b1000000 != 0 {
790- OperandConstraint :: FixedReg ( PReg :: new ( constraint_field & 0b0111111 , self . class ( ) ) )
805+ let mut hw_enc = constraint_field & 0b0111111 ;
806+ if class_field == 3 {
807+ hw_enc |= 1 << 6 ;
808+ }
809+ OperandConstraint :: FixedReg ( PReg :: new ( hw_enc, self . class ( ) ) )
791810 } else if constraint_field & 0b0100000 != 0 {
792811 OperandConstraint :: Reuse ( constraint_field & 0b0011111 )
793812 } else {
0 commit comments