Add reference types R32 and R64
-Add resumable_trap, safepoint, isnull, and null instructions -Add Stackmap struct and StackmapSink trait Co-authored-by: Mir Ahmed <mirahmed753@gmail.com> Co-authored-by: Dan Gohman <sunfish@mozilla.com>
This commit is contained in:
@@ -85,6 +85,12 @@ pub fn define(
|
||||
TypeSetBuilder::new().ints(32..64).build(),
|
||||
);
|
||||
|
||||
let Ref = &TypeVar::new(
|
||||
"Ref",
|
||||
"A scalar reference type",
|
||||
TypeSetBuilder::new().refs(Interval::All).build(),
|
||||
);
|
||||
|
||||
let Testable = &TypeVar::new(
|
||||
"Testable",
|
||||
"A scalar boolean or integer type",
|
||||
@@ -118,11 +124,12 @@ pub fn define(
|
||||
|
||||
let Any = &TypeVar::new(
|
||||
"Any",
|
||||
"Any integer, float, or boolean scalar or vector type",
|
||||
"Any integer, float, boolean, or reference scalar or vector type",
|
||||
TypeSetBuilder::new()
|
||||
.ints(Interval::All)
|
||||
.floats(Interval::All)
|
||||
.bools(Interval::All)
|
||||
.refs(Interval::All)
|
||||
.simd_lanes(Interval::All)
|
||||
.includes_scalars(true)
|
||||
.build(),
|
||||
@@ -394,6 +401,19 @@ pub fn define(
|
||||
.can_trap(true),
|
||||
);
|
||||
|
||||
ig.push(
|
||||
Inst::new(
|
||||
"resumable_trap",
|
||||
r#"
|
||||
A resumable trap.
|
||||
|
||||
This instruction allows non-conditional traps to be used as non-terminal instructions.
|
||||
"#,
|
||||
)
|
||||
.operands_in(vec![code])
|
||||
.can_trap(true),
|
||||
);
|
||||
|
||||
ig.push(
|
||||
Inst::new(
|
||||
"trapnz",
|
||||
@@ -1068,6 +1088,20 @@ pub fn define(
|
||||
.operands_out(vec![a]),
|
||||
);
|
||||
|
||||
let a = &operand_doc("a", Ref, "A constant reference null value");
|
||||
|
||||
ig.push(
|
||||
Inst::new(
|
||||
"null",
|
||||
r#"
|
||||
Null constant value for reference types.
|
||||
|
||||
Create a scalar reference SSA value with a constant null value.
|
||||
"#,
|
||||
)
|
||||
.operands_out(vec![a]),
|
||||
);
|
||||
|
||||
ig.push(Inst::new(
|
||||
"nop",
|
||||
r#"
|
||||
@@ -1315,6 +1349,24 @@ pub fn define(
|
||||
.other_side_effects(true),
|
||||
);
|
||||
|
||||
let N = &operand_doc(
|
||||
"args",
|
||||
variable_args,
|
||||
"Variable number of args for Stackmap",
|
||||
);
|
||||
|
||||
ig.push(
|
||||
Inst::new(
|
||||
"safepoint",
|
||||
r#"
|
||||
This instruction will provide live reference values at a point in
|
||||
the function. It can only be used by the compiler.
|
||||
"#,
|
||||
)
|
||||
.operands_in(vec![N])
|
||||
.other_side_effects(true),
|
||||
);
|
||||
|
||||
let x = &operand_doc("x", TxN, "Vector to split");
|
||||
let lo = &operand_doc("lo", &TxN.half_vector(), "Low-numbered lanes of `x`");
|
||||
let hi = &operand_doc("hi", &TxN.half_vector(), "High-numbered lanes of `x`");
|
||||
@@ -2578,6 +2630,23 @@ pub fn define(
|
||||
.operands_out(vec![a]),
|
||||
);
|
||||
|
||||
let a = &operand("a", b1);
|
||||
let x = &operand("x", Ref);
|
||||
|
||||
ig.push(
|
||||
Inst::new(
|
||||
"is_null",
|
||||
r#"
|
||||
Reference verification.
|
||||
|
||||
The condition code determines if the reference type in question is
|
||||
null or not.
|
||||
"#,
|
||||
)
|
||||
.operands_in(vec![x])
|
||||
.operands_out(vec![a]),
|
||||
);
|
||||
|
||||
let Cond = &operand("Cond", intcc);
|
||||
let f = &operand("f", iflags);
|
||||
let a = &operand("a", b1);
|
||||
|
||||
@@ -92,6 +92,18 @@ pub fn define() -> SettingGroup {
|
||||
true,
|
||||
);
|
||||
|
||||
settings.add_bool(
|
||||
"enable_safepoints",
|
||||
r#"
|
||||
Enable safepoint instruction insertions.
|
||||
|
||||
This will allow the emit_stackmaps() function to insert the safepoint
|
||||
instruction on top of calls and interrupt traps in order to display the
|
||||
live reference values at that point in the program.
|
||||
"#,
|
||||
false,
|
||||
);
|
||||
|
||||
// Settings specific to the `baldrdash` calling convention.
|
||||
|
||||
settings.add_enum(
|
||||
|
||||
@@ -145,6 +145,38 @@ impl Iterator for FlagIterator {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
|
||||
pub enum Reference {
|
||||
/// 32-bit reference.
|
||||
R32 = 32,
|
||||
/// 64-bit reference.
|
||||
R64 = 64,
|
||||
}
|
||||
|
||||
/// This provides an iterator through all of the supported reference variants.
|
||||
pub struct ReferenceIterator {
|
||||
index: u8,
|
||||
}
|
||||
|
||||
impl ReferenceIterator {
|
||||
pub fn new() -> Self {
|
||||
Self { index: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
impl Iterator for ReferenceIterator {
|
||||
type Item = Reference;
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let res = match self.index {
|
||||
0 => Some(Reference::R32),
|
||||
1 => Some(Reference::R64),
|
||||
_ => return None,
|
||||
};
|
||||
self.index += 1;
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod iter_tests {
|
||||
use super::*;
|
||||
@@ -185,4 +217,12 @@ mod iter_tests {
|
||||
assert_eq!(flag_iter.next(), Some(Flag::FFlags));
|
||||
assert_eq!(flag_iter.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reference_iter_works() {
|
||||
let mut reference_iter = ReferenceIterator::new();
|
||||
assert_eq!(reference_iter.next(), Some(Reference::R32));
|
||||
assert_eq!(reference_iter.next(), Some(Reference::R64));
|
||||
assert_eq!(reference_iter.next(), None);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user