Skip to content

Commit 6080822

Browse files
committed
Extend integer register PReg space to 128 registers
1 parent 5d79e12 commit 6080822

File tree

2 files changed

+54
-21
lines changed

2 files changed

+54
-21
lines changed

src/fuzzing/func.rs

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,13 @@ impl Func {
470470
// Pick an operand and make it a fixed reg.
471471
let i = u.int_in_range(0..=(operands.len() - 1))?;
472472
let op = operands[i];
473-
let fixed_reg = PReg::new(u.int_in_range(0..=62)?, op.class());
473+
let fixed_reg = PReg::new(
474+
match op.class() {
475+
RegClass::Int => u.int_in_range(0..=119)?,
476+
RegClass::Float | RegClass::Vector => u.int_in_range(0..=62)?,
477+
},
478+
op.class(),
479+
);
474480
let fixed_list = match op.pos() {
475481
OperandPos::Early => &mut fixed_early,
476482
OperandPos::Late => &mut fixed_late,
@@ -511,9 +517,13 @@ impl Func {
511517
clobbers.push(PReg::new(reg, RegClass::arbitrary(u)?));
512518
}
513519
} else if opts.fixed_nonallocatable && bool::arbitrary(u)? {
520+
let class = RegClass::arbitrary(u)?;
514521
operands.push(Operand::fixed_nonallocatable(PReg::new(
515-
63,
516-
RegClass::arbitrary(u)?,
522+
match class {
523+
RegClass::Int => 121,
524+
RegClass::Float | RegClass::Vector => 63,
525+
},
526+
class,
517527
)));
518528
}
519529

@@ -658,16 +668,20 @@ pub fn machine_env() -> MachineEnv {
658668
regs(24..32, RegClass::Vector),
659669
];
660670
let scratch_by_class: [Option<PReg>; 3] = [None, None, None];
661-
let fixed_stack_slots = (32..63)
671+
let fixed_stack_slots = (32..120)
662672
.flat_map(|i| {
663-
[
664-
PReg::new(i, RegClass::Int),
665-
PReg::new(i, RegClass::Float),
666-
PReg::new(i, RegClass::Vector),
667-
]
673+
if i < 63 {
674+
vec![
675+
PReg::new(i, RegClass::Int),
676+
PReg::new(i, RegClass::Float),
677+
PReg::new(i, RegClass::Vector),
678+
]
679+
} else {
680+
vec![PReg::new(i, RegClass::Int)]
681+
}
668682
})
669683
.collect();
670-
// Register 63 is reserved for use as a fixed non-allocatable register.
684+
// Register 63/121 is reserved for use as a fixed non-allocatable register.
671685
MachineEnv {
672686
preferred_regs_by_class,
673687
non_preferred_regs_by_class,

src/lib.rs

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -106,30 +106,41 @@ pub struct PReg {
106106
}
107107

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

Comments
 (0)