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:
Chris Fallin
2020-11-11 13:30:14 -08:00
parent 8af2dbfbac
commit 5df8840483
7 changed files with 167 additions and 33 deletions

View File

@@ -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 {