@@ -103,30 +103,41 @@ pub struct PReg {
103103}
104104
105105impl PReg {
106- pub const MAX_BITS : usize = 6 ;
106+ const MAX_BITS : usize = 6 ;
107107 pub const MAX : usize = ( 1 << Self :: MAX_BITS ) - 1 ;
108+ pub const MAX_INT : usize = ( 2 << Self :: MAX_BITS ) - 1 ;
108109 pub const NUM_INDEX : usize = 1 << ( Self :: MAX_BITS + 2 ) ; // including RegClass bits
109110
110111 /// Create a new PReg. The `hw_enc` range is 6 bits.
111112 #[ inline( always) ]
112113 pub const fn new ( hw_enc : usize , class : RegClass ) -> Self {
113- debug_assert ! ( hw_enc <= PReg :: MAX ) ;
114+ match class {
115+ RegClass :: Int => debug_assert ! ( hw_enc <= PReg :: MAX_INT ) ,
116+ RegClass :: Float | RegClass :: Vector => debug_assert ! ( hw_enc <= PReg :: MAX ) ,
117+ }
118+ let mut class = class as u8 ;
119+ if class == 0 && hw_enc > PReg :: MAX {
120+ class = 3 ;
121+ }
114122 PReg {
115- bits : ( ( class as u8 ) << Self :: MAX_BITS ) | ( hw_enc as u8 ) ,
123+ bits : ( class << Self :: MAX_BITS ) | ( ( hw_enc & PReg :: MAX ) as u8 ) ,
116124 }
117125 }
118126
119127 /// The physical register number, as encoded by the ISA for the particular register class.
120128 #[ inline( always) ]
121129 pub const fn hw_enc ( self ) -> usize {
122- self . bits as usize & Self :: MAX
130+ match self . class ( ) {
131+ RegClass :: Int => self . bits as usize & Self :: MAX_INT ,
132+ RegClass :: Float | RegClass :: Vector => self . bits as usize & Self :: MAX ,
133+ }
123134 }
124135
125136 /// The register class.
126137 #[ inline( always) ]
127138 pub const fn class ( self ) -> RegClass {
128139 match ( self . bits >> Self :: MAX_BITS ) & 0b11 {
129- 0 => RegClass :: Int ,
140+ 0 | 3 => RegClass :: Int ,
130141 1 => RegClass :: Float ,
131142 2 => RegClass :: Vector ,
132143 _ => unreachable ! ( ) ,
@@ -153,7 +164,7 @@ impl PReg {
153164 /// data structures.
154165 #[ inline( always) ]
155166 pub const fn invalid ( ) -> Self {
156- PReg :: new ( Self :: MAX , RegClass :: Int )
167+ PReg :: new ( Self :: MAX_INT , RegClass :: Int )
157168 }
158169}
159170
@@ -311,7 +322,7 @@ impl VReg {
311322 pub const fn new ( virt_reg : usize , class : RegClass ) -> Self {
312323 debug_assert ! ( virt_reg <= VReg :: MAX ) ;
313324 VReg {
314- bits : ( ( virt_reg as u32 ) << 2 ) | ( class as u8 as u32 ) ,
325+ bits : ( ( virt_reg as u32 ) << 2 ) | ( class as u32 ) ,
315326 }
316327 }
317328
@@ -537,20 +548,23 @@ impl Operand {
537548 kind : OperandKind ,
538549 pos : OperandPos ,
539550 ) -> Self {
551+ let mut class_field = vreg. class ( ) as u32 ;
540552 let constraint_field = match constraint {
541553 OperandConstraint :: Any => 0 ,
542554 OperandConstraint :: Reg => 1 ,
543555 OperandConstraint :: Stack => 2 ,
544556 OperandConstraint :: FixedReg ( preg) => {
545557 debug_assert_eq ! ( preg. class( ) , vreg. class( ) ) ;
546- 0b1000000 | preg. hw_enc ( ) as u32
558+ if preg. hw_enc ( ) & 0b1000000 != 0 {
559+ class_field = 3 ;
560+ }
561+ 0b1000000 | ( preg. hw_enc ( ) & PReg :: MAX ) as u32
547562 }
548563 OperandConstraint :: Reuse ( which) => {
549564 debug_assert ! ( which <= 31 ) ;
550565 0b0100000 | which as u32
551566 }
552567 } ;
553- let class_field = vreg. class ( ) as u8 as u32 ;
554568 let pos_field = pos as u8 as u32 ;
555569 let kind_field = kind as u8 as u32 ;
556570 Operand {
@@ -745,7 +759,7 @@ impl Operand {
745759 pub fn class ( self ) -> RegClass {
746760 let class_field = ( self . bits >> 21 ) & 3 ;
747761 match class_field {
748- 0 => RegClass :: Int ,
762+ 0 | 3 => RegClass :: Int ,
749763 1 => RegClass :: Float ,
750764 2 => RegClass :: Vector ,
751765 _ => unreachable ! ( ) ,
@@ -782,9 +796,14 @@ impl Operand {
782796 /// its allocation must fulfill.
783797 #[ inline( always) ]
784798 pub fn constraint ( self ) -> OperandConstraint {
799+ let class_field = ( self . bits >> 21 ) as usize & 3 ;
785800 let constraint_field = ( ( self . bits >> 25 ) as usize ) & 127 ;
786801 if constraint_field & 0b1000000 != 0 {
787- OperandConstraint :: FixedReg ( PReg :: new ( constraint_field & 0b0111111 , self . class ( ) ) )
802+ let mut hw_enc = constraint_field & 0b0111111 ;
803+ if class_field == 3 {
804+ hw_enc |= 1 << 6 ;
805+ }
806+ OperandConstraint :: FixedReg ( PReg :: new ( hw_enc, self . class ( ) ) )
788807 } else if constraint_field & 0b0100000 != 0 {
789808 OperandConstraint :: Reuse ( constraint_field & 0b0011111 )
790809 } else {
0 commit comments