Skip to content

Commit

Permalink
wip cheri
Browse files Browse the repository at this point in the history
  • Loading branch information
martin-fink committed Jan 25, 2024
1 parent b9144e6 commit a0ae8b5
Show file tree
Hide file tree
Showing 18 changed files with 589 additions and 72 deletions.
94 changes: 56 additions & 38 deletions cranelift/codegen/meta/src/cdsl/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,6 @@ impl From<DynamicVectorType> for ValueType {
pub(crate) enum LaneType {
Float(shared_types::Float),
Int(shared_types::Int),
CapPointer(shared_types::CapPointer),
}

impl LaneType {
Expand All @@ -154,7 +153,6 @@ impl LaneType {
self.lane_bits()
),
LaneType::Int(_) => format!("An integer type with {} bits.", self.lane_bits()),
LaneType::CapPointer(_) => format!("A capability-carrying pointertype with {} bits.", self.lane_bits()),
}
}

Expand All @@ -163,7 +161,6 @@ impl LaneType {
match self {
LaneType::Float(ref f) => *f as u64,
LaneType::Int(ref i) => *i as u64,
LaneType::CapPointer(ref c) => *c as u64,
}
}

Expand All @@ -178,7 +175,6 @@ impl LaneType {
LaneType::Int(shared_types::Int::I128) => 10,
LaneType::Float(shared_types::Float::F32) => 11,
LaneType::Float(shared_types::Float::F64) => 12,
LaneType::CapPointer(shared_types::CapPointer::C64) => 13,
}
}

Expand All @@ -193,13 +189,6 @@ impl LaneType {
})
}

pub fn cap_from_bits(num_bits: u16) -> LaneType {
LaneType::CapPointer(match num_bits {
64 => shared_types::CapPointer::C64,
_ => unreachable!("unxpected num bits for cap"),
})
}

pub fn float_from_bits(num_bits: u16) -> LaneType {
LaneType::Float(match num_bits {
32 => shared_types::Float::F32,
Expand All @@ -226,7 +215,6 @@ impl fmt::Display for LaneType {
match *self {
LaneType::Float(_) => write!(f, "f{}", self.lane_bits()),
LaneType::Int(_) => write!(f, "i{}", self.lane_bits()),
LaneType::CapPointer(_) => write!(f, "c{}", self.lane_bits()),
}
}
}
Expand All @@ -240,7 +228,6 @@ impl fmt::Debug for LaneType {
match *self {
LaneType::Float(_) => format!("FloatType({})", inner_msg),
LaneType::Int(_) => format!("IntType({})", inner_msg),
LaneType::CapPointer(_) => format!("CapPointerType({})", inner_msg),
}
)
}
Expand All @@ -260,18 +247,10 @@ impl From<shared_types::Int> for LaneType {
}
}

/// Create a LaneType from a given cap variant.
impl From<shared_types::CapPointer> for LaneType {
fn from(c: shared_types::CapPointer) -> Self {
LaneType::CapPointer(c)
}
}

/// An iterator for different lane types.
pub(crate) struct LaneTypeIterator {
int_iter: shared_types::IntIterator,
float_iter: shared_types::FloatIterator,
cap_iter: shared_types::CapPointerIterator,
}

impl LaneTypeIterator {
Expand All @@ -280,7 +259,6 @@ impl LaneTypeIterator {
Self {
int_iter: shared_types::IntIterator::new(),
float_iter: shared_types::FloatIterator::new(),
cap_iter: shared_types::CapPointerIterator::new(),
}
}
}
Expand All @@ -292,8 +270,6 @@ impl Iterator for LaneTypeIterator {
Some(LaneType::from(i))
} else if let Some(f) = self.float_iter.next() {
Some(LaneType::from(f))
} else if let Some(c) = self.cap_iter.next() {
Some(LaneType::from(c))
} else {
None
}
Expand Down Expand Up @@ -445,76 +421,118 @@ impl fmt::Debug for DynamicVectorType {

/// Reference type is scalar type, but not lane type.
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub(crate) struct ReferenceType(pub shared_types::Reference);
pub(crate) enum ReferenceType {
ReferenceType(shared_types::Reference),
CapPointer(shared_types::CapPointer),
}

impl ReferenceType {
/// Return a string containing the documentation comment for this reference type.
pub fn doc(self) -> String {
format!("An opaque reference type with {} bits.", self.lane_bits())
let ty = match self {
ReferenceType::ReferenceType(_) => "reference",
ReferenceType::CapPointer(_) => "capability pointer",
};
format!("An opaque {} type with {} bits.", ty, self.lane_bits())
}

/// Return the number of bits in a lane.
pub fn lane_bits(self) -> u64 {
match self.0 {
shared_types::Reference::R32 => 32,
shared_types::Reference::R64 => 64,
match self {
ReferenceType::ReferenceType(shared_types::Reference::R32) => 32,
ReferenceType::ReferenceType(shared_types::Reference::R64) => 64,
ReferenceType::CapPointer(shared_types::CapPointer::C64) => 64,
}
}

/// Find the unique number associated with this reference type.
pub fn number(self) -> u16 {
constants::REFERENCE_BASE
+ match self {
ReferenceType(shared_types::Reference::R32) => 0,
ReferenceType(shared_types::Reference::R64) => 1,
match self {
ReferenceType::ReferenceType(shared_types::Reference::R32) => {
constants::REFERENCE_BASE + 0
}
ReferenceType::ReferenceType(shared_types::Reference::R64) => {
constants::REFERENCE_BASE + 1
}
ReferenceType::CapPointer(shared_types::CapPointer::C64) => constants::LANE_BASE + 5,
}
}

pub fn ref_from_bits(num_bits: u16) -> ReferenceType {
ReferenceType(match num_bits {
ReferenceType::ReferenceType(match num_bits {
32 => shared_types::Reference::R32,
64 => shared_types::Reference::R64,
_ => unreachable!("unexpected number of bits for a reference type"),
})
}

pub fn cap_from_bits(num_bits: u16) -> ReferenceType {
ReferenceType::CapPointer(match num_bits {
64 => shared_types::CapPointer::C64,
_ => unreachable!("unexpected number of bits for a capability pointer type"),
})
}
}

impl fmt::Display for ReferenceType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "r{}", self.lane_bits())
let prefix = match self {
ReferenceType::ReferenceType(_) => "r",
ReferenceType::CapPointer(_) => "c",
};
write!(f, "{}{}", prefix, self.lane_bits())
}
}

impl fmt::Debug for ReferenceType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "ReferenceType(bits={})", self.lane_bits())
let ty = match self {
ReferenceType::ReferenceType(_) => "ReferenceType",
ReferenceType::CapPointer(_) => "CapPointerType",
};
write!(f, "{}(bits={})", ty, self.lane_bits())
}
}

/// Create a ReferenceType from a given reference variant.
impl From<shared_types::Reference> for ReferenceType {
fn from(r: shared_types::Reference) -> Self {
ReferenceType(r)
ReferenceType::ReferenceType(r)
}
}

/// Create a ReferenceType from a given capability pointer variant.
impl From<shared_types::CapPointer> for ReferenceType {
fn from(c: shared_types::CapPointer) -> Self {
ReferenceType::CapPointer(c)
}
}

/// An iterator for different reference types.
pub(crate) struct ReferenceTypeIterator {
reference_iter: shared_types::ReferenceIterator,
cap_ptr_iter: shared_types::CapPointerIterator,
}

impl ReferenceTypeIterator {
/// Create a new reference type iterator.
fn new() -> Self {
Self {
reference_iter: shared_types::ReferenceIterator::new(),
cap_ptr_iter: shared_types::CapPointerIterator::new(),
}
}
}

impl Iterator for ReferenceTypeIterator {
type Item = ReferenceType;
fn next(&mut self) -> Option<Self::Item> {
self.reference_iter.next().map(ReferenceType::from)
if let Some(r) = self.reference_iter.next() {
Some(ReferenceType::from(r))
} else if let Some(c) = self.cap_ptr_iter.next() {
Some(ReferenceType::from(c))
} else {
None
}
}
}
15 changes: 8 additions & 7 deletions cranelift/codegen/meta/src/cdsl/typevar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,14 @@ impl TypeVar {
let mut builder = TypeSetBuilder::new();

let (scalar_type, num_lanes) = match value_type {
ValueType::Reference(ReferenceType(reference_type)) => {
ValueType::Reference(ReferenceType::ReferenceType(reference_type)) => {
let bits = reference_type as RangeBound;
return TypeVar::new(name, doc, builder.refs(bits..bits).build());
}
ValueType::Reference(ReferenceType::CapPointer(reference_type)) => {
let bits = reference_type as RangeBound;
return TypeVar::new(name, doc, builder.cap_ptrs(bits..bits).build());
}
ValueType::Lane(lane_type) => (lane_type, 1),
ValueType::Vector(vec_type) => {
(vec_type.lane_type(), vec_type.lane_count() as RangeBound)
Expand All @@ -87,10 +91,6 @@ impl TypeVar {
let bits = float_type as RangeBound;
builder.floats(bits..bits)
}
LaneType::CapPointer(cap_type) => {
let bits = cap_type as RangeBound;
builder.cap_ptrs(bits..bits)
}
};
TypeVar::new(name, doc, builder.build())
}
Expand Down Expand Up @@ -424,7 +424,8 @@ impl TypeSet {

/// Return the number of concrete types represented by this typeset.
pub fn size(&self) -> usize {
self.lanes.len() * (self.ints.len() + self.floats.len() + self.refs.len() + self.cap_ptrs.len())
self.lanes.len()
* (self.ints.len() + self.floats.len() + self.refs.len() + self.cap_ptrs.len())
+ self.dynamic_lanes.len() * (self.ints.len() + self.floats.len() + self.refs.len())
}

Expand Down Expand Up @@ -533,7 +534,7 @@ impl TypeSet {
ret.push(ReferenceType::ref_from_bits(bits).into());
}
for &bits in &self.cap_ptrs {
ret.push(LaneType::cap_from_bits(bits).into());
ret.push(ReferenceType::cap_from_bits(bits).into());
}
}
for &num_lanes in &self.dynamic_lanes {
Expand Down
1 change: 1 addition & 0 deletions cranelift/codegen/meta/src/gen_inst.rs
Original file line number Diff line number Diff line change
Expand Up @@ -775,6 +775,7 @@ pub(crate) fn gen_typesets_table(type_sets: &UniqueTable<TypeSet>, fmt: &mut For
gen_bitset(&ts.ints, "ints", 8, fmt);
gen_bitset(&ts.floats, "floats", 8, fmt);
gen_bitset(&ts.refs, "refs", 8, fmt);
gen_bitset(&ts.cap_ptrs, "cap_ptrs", 8, fmt);
});
fmt.line("},");
}
Expand Down
28 changes: 15 additions & 13 deletions cranelift/codegen/meta/src/shared/instructions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -650,12 +650,13 @@ pub(crate) fn define(
TypeSetBuilder::new().ints(8..64).build(),
);

// TODO: add capability ptrs
let Cap = &dbg!(TypeVar::new(
"CapInt",
"A capability carrying pointer",
TypeSetBuilder::new().cap_ptrs(64..64).build(),
));
// // TODO: add capability ptrs
// let Cap = &dbg!(TypeVar::new(
// "CapInt",
// "A capability carrying pointer",
// TypeSetBuilder::new().cap_ptrs(64..64).build(),
// ));
let Cap = Int;

let ScalarTruthy = &TypeVar::new(
"ScalarTruthy",
Expand Down Expand Up @@ -718,6 +719,7 @@ pub(crate) fn define(
.simd_lanes(Interval::All)
.refs(Interval::All)
.dynamic_simd_lanes(Interval::All)
.cap_ptrs(Interval::All)
.build(),
);

Expand Down Expand Up @@ -3824,12 +3826,12 @@ pub(crate) fn define(
"#,
&formats.binary,
)
.operands_in(vec![
Operand::new("x", Cap).with_doc("The first capability"),
Operand::new("y", Int).with_doc("The value being added"),
])
.operands_out(vec![
Operand::new("a", Cap).with_doc("The result of the addition"),
])
.operands_in(vec![
Operand::new("x", Cap).with_doc("The first capability"),
Operand::new("y", Int).with_doc("The value being added"),
])
.operands_out(vec![
Operand::new("a", Cap).with_doc("The result of the addition")
]),
);
}
10 changes: 10 additions & 0 deletions cranelift/codegen/src/ir/instructions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,8 @@ pub struct ValueTypeSet {
pub refs: BitSet8,
/// Allowed dynamic vectors minimum lane sizes
pub dynamic_lanes: BitSet16,
/// Allowed cheri pointer types
pub cap_ptrs: BitSet8,
}

impl ValueTypeSet {
Expand All @@ -637,6 +639,8 @@ impl ValueTypeSet {
self.floats.contains(l2b)
} else if scalar.is_ref() {
self.refs.contains(l2b)
} else if scalar.is_cap_ptr() {
self.cap_ptrs.contains(l2b)
} else {
false
}
Expand Down Expand Up @@ -946,6 +950,7 @@ mod tests {
floats: BitSet8::from_range(0, 0),
refs: BitSet8::from_range(5, 7),
dynamic_lanes: BitSet16::from_range(0, 4),
cap_ptrs: BitSet8::from_range(6, 6),
};
assert!(!vts.contains(I8));
assert!(vts.contains(I32));
Expand All @@ -955,6 +960,7 @@ mod tests {
assert!(!vts.contains(F32));
assert!(vts.contains(R32));
assert!(vts.contains(R64));
assert!(vts.contains(C64));
assert_eq!(vts.example().to_string(), "i32");

let vts = ValueTypeSet {
Expand All @@ -963,6 +969,7 @@ mod tests {
floats: BitSet8::from_range(5, 7),
refs: BitSet8::from_range(0, 0),
dynamic_lanes: BitSet16::from_range(0, 8),
cap_ptrs: BitSet8::from_range(0, 0),
};
assert_eq!(vts.example().to_string(), "f32");

Expand All @@ -972,6 +979,7 @@ mod tests {
floats: BitSet8::from_range(5, 7),
refs: BitSet8::from_range(0, 0),
dynamic_lanes: BitSet16::from_range(0, 8),
cap_ptrs: BitSet8::from_range(0, 0),
};
assert_eq!(vts.example().to_string(), "f32x2");

Expand All @@ -981,6 +989,7 @@ mod tests {
floats: BitSet8::from_range(0, 0),
refs: BitSet8::from_range(0, 0),
dynamic_lanes: BitSet16::from_range(0, 8),
cap_ptrs: BitSet8::from_range(0, 0),
};
assert_eq!(vts.example().to_string(), "i32x4");

Expand All @@ -991,6 +1000,7 @@ mod tests {
floats: BitSet8::from_range(0, 0),
refs: BitSet8::from_range(0, 0),
dynamic_lanes: BitSet16::from_range(0, 8),
cap_ptrs: BitSet8::from_range(0, 0),
};
assert!(vts.contains(I32));
assert!(vts.contains(I32X4));
Expand Down
Loading

0 comments on commit a0ae8b5

Please sign in to comment.