Add support for brff/brif and icmp_sp to new x64 backend to support Lucet.
`lucetc` currently *almost*, but not quite, works with the new x64 backend; the only missing piece is support for the particular instructions emitted as part of its prologue stack-check. We do not normally see `brff`, `brif`, or `ifcmp_sp` in CLIF generated by `cranelift-wasm` without the old-backend legalization rules, so these were not supported in the new x64 backend as they were not necessary for Wasm MVP support. Using them resulted in an `unimplemented!()` panic. This PR adds support for `brff` and `brif` analogously to how AArch64 implements them, by pattern-matching the `ifcmp` / `ffcmp` directly. Then `ifcmp_sp` is a straightforward variant of `ifcmp`. Along the way, this also removes the notion of "fallthrough block" from the branch-group lowering method; instead, `fallthrough` instructions are handled as normal branches to their explicitly-provided targets, which (in the original CLIF) match the fallthrough block. The reason for this is that the block reordering done as part of lowering can change the fallthrough block. We were not using `fallthrough` instructions in the output produced by `cranelift-wasm`, so this, too, was not previously caught. With these changes, the `lucetc` crate in Lucet passes all tests with the `x64` feature-flag added to its `cranelift-codegen` dependency.
This commit is contained in:
@@ -209,7 +209,6 @@ pub trait LowerBackend {
|
||||
ctx: &mut C,
|
||||
insts: &[Inst],
|
||||
targets: &[MachLabel],
|
||||
fallthrough: Option<MachLabel>,
|
||||
) -> CodegenResult<()>;
|
||||
|
||||
/// A bit of a hack: give a fixed register that always holds the result of a
|
||||
@@ -663,13 +662,12 @@ impl<'func, I: VCodeInst> Lower<'func, I> {
|
||||
block: Block,
|
||||
branches: &SmallVec<[Inst; 2]>,
|
||||
targets: &SmallVec<[MachLabel; 2]>,
|
||||
maybe_fallthrough: Option<MachLabel>,
|
||||
) -> CodegenResult<()> {
|
||||
debug!(
|
||||
"lower_clif_branches: block {} branches {:?} targets {:?} maybe_fallthrough {:?}",
|
||||
block, branches, targets, maybe_fallthrough
|
||||
"lower_clif_branches: block {} branches {:?} targets {:?}",
|
||||
block, branches, targets,
|
||||
);
|
||||
backend.lower_branch_group(self, branches, targets, maybe_fallthrough)?;
|
||||
backend.lower_branch_group(self, branches, targets)?;
|
||||
let loc = self.srcloc(branches[0]);
|
||||
self.finish_ir_inst(loc);
|
||||
Ok(())
|
||||
@@ -744,12 +742,7 @@ impl<'func, I: VCodeInst> Lower<'func, I> {
|
||||
if let Some(bb) = lb.orig_block() {
|
||||
self.collect_branches_and_targets(bindex, bb, &mut branches, &mut targets);
|
||||
if branches.len() > 0 {
|
||||
let maybe_fallthrough = if (bindex + 1) < (lowered_order.len() as BlockIndex) {
|
||||
Some(MachLabel::from_block(bindex + 1))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
self.lower_clif_branches(backend, bb, &branches, &targets, maybe_fallthrough)?;
|
||||
self.lower_clif_branches(backend, bb, &branches, &targets)?;
|
||||
self.finish_ir_inst(self.srcloc(branches[0]));
|
||||
}
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user