Skip to content

Commit 8376b00

Browse files
committed
Extend integer register PReg space to 128 registers
1 parent d3a4ee9 commit 8376b00

File tree

2 files changed

+34
-15
lines changed

2 files changed

+34
-15
lines changed

src/fuzzing/func.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,7 @@ impl Func {
497497
// Pick an operand and make it a fixed reg.
498498
let i = u.int_in_range(0..=(operands.len() - 1))?;
499499
let op = operands[i];
500-
let fixed_reg = PReg::new(u.int_in_range(0..=62)?, RegClass::Int);
500+
let fixed_reg = PReg::new(u.int_in_range(0..=119)?, RegClass::Int);
501501
let fixed_list = match op.pos() {
502502
OperandPos::Early => &mut fixed_early,
503503
OperandPos::Late => &mut fixed_late,
@@ -538,7 +538,7 @@ impl Func {
538538
clobbers.push(PReg::new(reg, RegClass::Int));
539539
}
540540
} else if opts.fixed_nonallocatable && bool::arbitrary(u)? {
541-
operands.push(Operand::fixed_nonallocatable(PReg::new(63, RegClass::Int)));
541+
operands.push(Operand::fixed_nonallocatable(PReg::new(121, RegClass::Int)));
542542
}
543543

544544
let is_safepoint = opts.reftypes
@@ -662,8 +662,8 @@ pub fn machine_env() -> MachineEnv {
662662
let preferred_regs_by_class: [Vec<PReg>; 3] = [regs(0..24), vec![], vec![]];
663663
let non_preferred_regs_by_class: [Vec<PReg>; 3] = [regs(24..32), vec![], vec![]];
664664
let scratch_by_class: [Option<PReg>; 3] = [None, None, None];
665-
let fixed_stack_slots = regs(32..63);
666-
// Register 63 is reserved for use as a fixed non-allocatable register.
665+
let fixed_stack_slots = regs(32..120);
666+
// Register 121 is reserved for use as a fixed non-allocatable register.
667667
MachineEnv {
668668
preferred_regs_by_class,
669669
non_preferred_regs_by_class,

src/lib.rs

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -103,30 +103,41 @@ pub struct PReg {
103103
}
104104

105105
impl 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

Comments
 (0)