Support wasm select instruction with V128-typed operands on AArch64.

* this requires upgrading to wasmparser 0.67.0.

* There are no CLIF side changes because the CLIF `select` instruction is
  polymorphic enough.

* on aarch64, there is unfortunately no conditional-move (csel) instruction on
  vectors.  This patch adds a synthetic instruction `VecCSel` which *does*
  behave like that.  At emit time, this is emitted as an if-then-else diamond
  (4 insns).

* aarch64 implementation is otherwise straightforwards.
This commit is contained in:
Julian Seward
2020-11-11 17:09:57 +01:00
committed by julian-seward1
parent 9ced345aed
commit 41e87a2f99
15 changed files with 122 additions and 18 deletions

View File

@@ -1016,6 +1016,15 @@ pub enum Inst {
size: VectorSize,
},
/// Vector conditional select, 128 bit. A synthetic instruction, which generates a 4-insn
/// control-flow diamond.
VecCSel {
rd: Writable<Reg>,
rn: Reg,
rm: Reg,
cond: Cond,
},
/// Move to the NZCV flags (actually a `MSR NZCV, Xn` insn).
MovToNZCV {
rn: Reg,
@@ -1732,6 +1741,11 @@ fn aarch64_get_regs(inst: &Inst, collector: &mut RegUsageCollector) {
collector.add_def(rd);
collector.add_use(rn);
}
&Inst::VecCSel { rd, rn, rm, .. } => {
collector.add_def(rd);
collector.add_use(rn);
collector.add_use(rm);
}
&Inst::FpuCmp32 { rn, rm } | &Inst::FpuCmp64 { rn, rm } => {
collector.add_use(rn);
collector.add_use(rm);
@@ -2343,6 +2357,16 @@ fn aarch64_map_regs<RUM: RegUsageMapper>(inst: &mut Inst, mapper: &RUM) {
map_def(mapper, rd);
map_use(mapper, rn);
}
&mut Inst::VecCSel {
ref mut rd,
ref mut rn,
ref mut rm,
..
} => {
map_def(mapper, rd);
map_use(mapper, rn);
map_use(mapper, rm);
}
&mut Inst::FpuCmp32 {
ref mut rn,
ref mut rm,
@@ -3591,6 +3615,13 @@ impl Inst {
format!("ld1r {{ {} }}, [{}]", rd, rn)
}
&Inst::VecCSel { rd, rn, rm, cond } => {
let rd = show_vreg_vector(rd.to_reg(), mb_rru, VectorSize::Size8x16);
let rn = show_vreg_vector(rn, mb_rru, VectorSize::Size8x16);
let rm = show_vreg_vector(rm, mb_rru, VectorSize::Size8x16);
let cond = cond.show_rru(mb_rru);
format!("vcsel {}, {}, {}, {} (if-then-else diamond)", rd, rn, rm, cond)
}
&Inst::MovToNZCV { rn } => {
let rn = rn.show_rru(mb_rru);
format!("msr nzcv, {}", rn)