CL/aarch64 back end: implement the wasm SIMD bitmask instructions

The `bitmask.{8x16,16x8,32x4}` instructions do not map neatly to any single
AArch64 SIMD instruction, and instead need a sequence of around ten
instructions.  Because of this, this patch is somewhat longer and more complex
than it would be for (eg) x64.

Main changes are:

* the relevant testsuite test (`simd_boolean.wast`) has been enabled on aarch64.

* at the CLIF level, add a new instruction `vhigh_bits`, into which these wasm
  instructions are to be translated.

* in the wasm->CLIF translation (code_translator.rs), translate into
  `vhigh_bits`.  This is straightforward.

* in the CLIF->AArch64 translation (lower_inst.rs), translate `vhigh_bits`
  into equivalent sequences of AArch64 instructions.  There is a different
  sequence for each of the `{8x16, 16x8, 32x4}` variants.

All other changes are AArch64-specific, and add instruction definitions needed
by the previous step:

* Add two new families of AArch64 instructions: `VecShiftImm` (vector shift by
  immediate) and `VecExtract` (effectively a double-length vector shift)

* To the existing AArch64 family `VecRRR`, add a `zip1` variant.  To the
  `VecLanesOp` family add an `addv` variant.

* Add supporting code for the above changes to AArch64 instructions:
  - getting the register uses (`aarch64_get_regs`)
  - mapping the registers (`aarch64_map_regs`)
  - printing instructions
  - emitting instructions (`impl MachInstEmit for Inst`).  The handling of
    `VecShiftImm` is a bit complex.
  - emission tests for new instructions and variants.
This commit is contained in:
Julian Seward
2020-10-22 16:02:46 +02:00
committed by julian-seward1
parent b10e027fef
commit 2702942050
8 changed files with 570 additions and 5 deletions

View File

@@ -2193,6 +2193,24 @@ pub(crate) fn define(
.operands_out(vec![s]),
);
let a = &Operand::new("a", TxN);
let x = &Operand::new("x", Int);
ig.push(
Inst::new(
"vhigh_bits",
r#"
Reduce a vector to a scalar integer.
Return a scalar integer, consisting of the concatenation of the most significant bit
of each lane of ``a``.
"#,
&formats.unary,
)
.operands_in(vec![a])
.operands_out(vec![x]),
);
let a = &Operand::new("a", &Int.as_bool());
let Cond = &Operand::new("Cond", &imm.intcc);
let x = &Operand::new("x", Int);