@@ -106,30 +106,41 @@ pub struct PReg {
106
106
}
107
107
108
108
impl PReg {
109
- pub const MAX_BITS : usize = 6 ;
109
+ const MAX_BITS : usize = 6 ;
110
110
pub const MAX : usize = ( 1 << Self :: MAX_BITS ) - 1 ;
111
+ pub const MAX_INT : usize = ( 2 << Self :: MAX_BITS ) - 1 ;
111
112
pub const NUM_INDEX : usize = 1 << ( Self :: MAX_BITS + 2 ) ; // including RegClass bits
112
113
113
114
/// Create a new PReg. The `hw_enc` range is 6 bits.
114
115
#[ inline( always) ]
115
116
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
+ }
117
125
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 ) ,
119
127
}
120
128
}
121
129
122
130
/// The physical register number, as encoded by the ISA for the particular register class.
123
131
#[ inline( always) ]
124
132
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
+ }
126
137
}
127
138
128
139
/// The register class.
129
140
#[ inline( always) ]
130
141
pub const fn class ( self ) -> RegClass {
131
142
match ( self . bits >> Self :: MAX_BITS ) & 0b11 {
132
- 0 => RegClass :: Int ,
143
+ 0 | 3 => RegClass :: Int ,
133
144
1 => RegClass :: Float ,
134
145
2 => RegClass :: Vector ,
135
146
_ => unreachable ! ( ) ,
@@ -156,7 +167,7 @@ impl PReg {
156
167
/// data structures.
157
168
#[ inline( always) ]
158
169
pub const fn invalid ( ) -> Self {
159
- PReg :: new ( Self :: MAX , RegClass :: Int )
170
+ PReg :: new ( Self :: MAX_INT , RegClass :: Int )
160
171
}
161
172
}
162
173
@@ -314,7 +325,7 @@ impl VReg {
314
325
pub const fn new ( virt_reg : usize , class : RegClass ) -> Self {
315
326
debug_assert ! ( virt_reg <= VReg :: MAX ) ;
316
327
VReg {
317
- bits : ( ( virt_reg as u32 ) << 2 ) | ( class as u8 as u32 ) ,
328
+ bits : ( ( virt_reg as u32 ) << 2 ) | ( class as u32 ) ,
318
329
}
319
330
}
320
331
@@ -540,20 +551,23 @@ impl Operand {
540
551
kind : OperandKind ,
541
552
pos : OperandPos ,
542
553
) -> Self {
554
+ let mut class_field = vreg. class ( ) as u32 ;
543
555
let constraint_field = match constraint {
544
556
OperandConstraint :: Any => 0 ,
545
557
OperandConstraint :: Reg => 1 ,
546
558
OperandConstraint :: Stack => 2 ,
547
559
OperandConstraint :: FixedReg ( preg) => {
548
560
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
550
565
}
551
566
OperandConstraint :: Reuse ( which) => {
552
567
debug_assert ! ( which <= 31 ) ;
553
568
0b0100000 | which as u32
554
569
}
555
570
} ;
556
- let class_field = vreg. class ( ) as u8 as u32 ;
557
571
let pos_field = pos as u8 as u32 ;
558
572
let kind_field = kind as u8 as u32 ;
559
573
Operand {
@@ -748,7 +762,7 @@ impl Operand {
748
762
pub fn class ( self ) -> RegClass {
749
763
let class_field = ( self . bits >> 21 ) & 3 ;
750
764
match class_field {
751
- 0 => RegClass :: Int ,
765
+ 0 | 3 => RegClass :: Int ,
752
766
1 => RegClass :: Float ,
753
767
2 => RegClass :: Vector ,
754
768
_ => unreachable ! ( ) ,
@@ -785,9 +799,14 @@ impl Operand {
785
799
/// its allocation must fulfill.
786
800
#[ inline( always) ]
787
801
pub fn constraint ( self ) -> OperandConstraint {
802
+ let class_field = ( self . bits >> 21 ) as usize & 3 ;
788
803
let constraint_field = ( ( self . bits >> 25 ) as usize ) & 127 ;
789
804
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 ( ) ) )
791
810
} else if constraint_field & 0b0100000 != 0 {
792
811
OperandConstraint :: Reuse ( constraint_field & 0b0011111 )
793
812
} else {
0 commit comments