@@ -103,30 +103,41 @@ pub struct PReg {
103
103
}
104
104
105
105
impl PReg {
106
- pub const MAX_BITS : usize = 6 ;
106
+ const MAX_BITS : usize = 6 ;
107
107
pub const MAX : usize = ( 1 << Self :: MAX_BITS ) - 1 ;
108
+ pub const MAX_INT : usize = ( 2 << Self :: MAX_BITS ) - 1 ;
108
109
pub const NUM_INDEX : usize = 1 << ( Self :: MAX_BITS + 2 ) ; // including RegClass bits
109
110
110
111
/// Create a new PReg. The `hw_enc` range is 6 bits.
111
112
#[ inline( always) ]
112
113
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
+ }
114
122
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 ) ,
116
124
}
117
125
}
118
126
119
127
/// The physical register number, as encoded by the ISA for the particular register class.
120
128
#[ inline( always) ]
121
129
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
+ }
123
134
}
124
135
125
136
/// The register class.
126
137
#[ inline( always) ]
127
138
pub const fn class ( self ) -> RegClass {
128
139
match ( self . bits >> Self :: MAX_BITS ) & 0b11 {
129
- 0 => RegClass :: Int ,
140
+ 0 | 3 => RegClass :: Int ,
130
141
1 => RegClass :: Float ,
131
142
2 => RegClass :: Vector ,
132
143
_ => unreachable ! ( ) ,
@@ -153,7 +164,7 @@ impl PReg {
153
164
/// data structures.
154
165
#[ inline( always) ]
155
166
pub const fn invalid ( ) -> Self {
156
- PReg :: new ( Self :: MAX , RegClass :: Int )
167
+ PReg :: new ( Self :: MAX_INT , RegClass :: Int )
157
168
}
158
169
}
159
170
@@ -311,7 +322,7 @@ impl VReg {
311
322
pub const fn new ( virt_reg : usize , class : RegClass ) -> Self {
312
323
debug_assert ! ( virt_reg <= VReg :: MAX ) ;
313
324
VReg {
314
- bits : ( ( virt_reg as u32 ) << 2 ) | ( class as u8 as u32 ) ,
325
+ bits : ( ( virt_reg as u32 ) << 2 ) | ( class as u32 ) ,
315
326
}
316
327
}
317
328
@@ -537,20 +548,23 @@ impl Operand {
537
548
kind : OperandKind ,
538
549
pos : OperandPos ,
539
550
) -> Self {
551
+ let mut class_field = vreg. class ( ) as u32 ;
540
552
let constraint_field = match constraint {
541
553
OperandConstraint :: Any => 0 ,
542
554
OperandConstraint :: Reg => 1 ,
543
555
OperandConstraint :: Stack => 2 ,
544
556
OperandConstraint :: FixedReg ( preg) => {
545
557
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
547
562
}
548
563
OperandConstraint :: Reuse ( which) => {
549
564
debug_assert ! ( which <= 31 ) ;
550
565
0b0100000 | which as u32
551
566
}
552
567
} ;
553
- let class_field = vreg. class ( ) as u8 as u32 ;
554
568
let pos_field = pos as u8 as u32 ;
555
569
let kind_field = kind as u8 as u32 ;
556
570
Operand {
@@ -745,7 +759,7 @@ impl Operand {
745
759
pub fn class ( self ) -> RegClass {
746
760
let class_field = ( self . bits >> 21 ) & 3 ;
747
761
match class_field {
748
- 0 => RegClass :: Int ,
762
+ 0 | 3 => RegClass :: Int ,
749
763
1 => RegClass :: Float ,
750
764
2 => RegClass :: Vector ,
751
765
_ => unreachable ! ( ) ,
@@ -782,9 +796,14 @@ impl Operand {
782
796
/// its allocation must fulfill.
783
797
#[ inline( always) ]
784
798
pub fn constraint ( self ) -> OperandConstraint {
799
+ let class_field = ( self . bits >> 21 ) as usize & 3 ;
785
800
let constraint_field = ( ( self . bits >> 25 ) as usize ) & 127 ;
786
801
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 ( ) ) )
788
807
} else if constraint_field & 0b0100000 != 0 {
789
808
OperandConstraint :: Reuse ( constraint_field & 0b0011111 )
790
809
} else {
0 commit comments