CL/aarch64: implement the wasm SIMD pseudo-max/min and FP-rounding instructions
This patch implements, for aarch64, the following wasm SIMD extensions Floating-point rounding instructions https://github.com/WebAssembly/simd/pull/232 Pseudo-Minimum and Pseudo-Maximum instructions https://github.com/WebAssembly/simd/pull/122 The changes are straightforward: * `build.rs`: the relevant tests have been enabled * `cranelift/codegen/meta/src/shared/instructions.rs`: new CLIF instructions `fmin_pseudo` and `fmax_pseudo`. The wasm rounding instructions do not need any new CLIF instructions. * `cranelift/wasm/src/code_translator.rs`: translation into CLIF; this is pretty much the same as any other unary or binary vector instruction (for the rounding and the pmin/max respectively) * `cranelift/codegen/src/isa/aarch64/lower_inst.rs`: - `fmin_pseudo` and `fmax_pseudo` are converted into a two instruction sequence, `fcmpgt` followed by `bsl` - the CLIF rounding instructions are converted to a suitable vector `frint{n,z,p,m}` instruction. * `cranelift/codegen/src/isa/aarch64/inst/mod.rs`: minor extension of `pub enum VecMisc2` to handle the rounding operations. And corresponding `emit` cases.
This commit is contained in:
committed by
julian-seward1
parent
fc1cedb2ff
commit
c15d9bd61b
@@ -1430,6 +1430,22 @@ impl MachInstEmit for Inst {
|
||||
debug_assert!(size == VectorSize::Size32x4 || size == VectorSize::Size64x2);
|
||||
(0b1, 0b11101, enc_size & 0b1)
|
||||
}
|
||||
VecMisc2::Frintn => {
|
||||
debug_assert!(size == VectorSize::Size32x4 || size == VectorSize::Size64x2);
|
||||
(0b0, 0b11000, enc_size & 0b01)
|
||||
}
|
||||
VecMisc2::Frintz => {
|
||||
debug_assert!(size == VectorSize::Size32x4 || size == VectorSize::Size64x2);
|
||||
(0b0, 0b11001, enc_size | 0b10)
|
||||
}
|
||||
VecMisc2::Frintm => {
|
||||
debug_assert!(size == VectorSize::Size32x4 || size == VectorSize::Size64x2);
|
||||
(0b0, 0b11001, enc_size & 0b01)
|
||||
}
|
||||
VecMisc2::Frintp => {
|
||||
debug_assert!(size == VectorSize::Size32x4 || size == VectorSize::Size64x2);
|
||||
(0b0, 0b11000, enc_size | 0b10)
|
||||
}
|
||||
};
|
||||
sink.put4(enc_vec_rr_misc((q << 1) | u, size, bits_12_16, rd, rn));
|
||||
}
|
||||
|
||||
@@ -3476,6 +3476,94 @@ fn test_aarch64_binemit() {
|
||||
"ucvtf v10.2d, v19.2d",
|
||||
));
|
||||
|
||||
insns.push((
|
||||
Inst::VecMisc {
|
||||
op: VecMisc2::Frintn,
|
||||
rd: writable_vreg(11),
|
||||
rn: vreg(18),
|
||||
size: VectorSize::Size32x4,
|
||||
},
|
||||
"4B8A214E",
|
||||
"frintn v11.4s, v18.4s",
|
||||
));
|
||||
|
||||
insns.push((
|
||||
Inst::VecMisc {
|
||||
op: VecMisc2::Frintn,
|
||||
rd: writable_vreg(12),
|
||||
rn: vreg(17),
|
||||
size: VectorSize::Size64x2,
|
||||
},
|
||||
"2C8A614E",
|
||||
"frintn v12.2d, v17.2d",
|
||||
));
|
||||
|
||||
insns.push((
|
||||
Inst::VecMisc {
|
||||
op: VecMisc2::Frintz,
|
||||
rd: writable_vreg(11),
|
||||
rn: vreg(18),
|
||||
size: VectorSize::Size32x4,
|
||||
},
|
||||
"4B9AA14E",
|
||||
"frintz v11.4s, v18.4s",
|
||||
));
|
||||
|
||||
insns.push((
|
||||
Inst::VecMisc {
|
||||
op: VecMisc2::Frintz,
|
||||
rd: writable_vreg(12),
|
||||
rn: vreg(17),
|
||||
size: VectorSize::Size64x2,
|
||||
},
|
||||
"2C9AE14E",
|
||||
"frintz v12.2d, v17.2d",
|
||||
));
|
||||
|
||||
insns.push((
|
||||
Inst::VecMisc {
|
||||
op: VecMisc2::Frintm,
|
||||
rd: writable_vreg(11),
|
||||
rn: vreg(18),
|
||||
size: VectorSize::Size32x4,
|
||||
},
|
||||
"4B9A214E",
|
||||
"frintm v11.4s, v18.4s",
|
||||
));
|
||||
|
||||
insns.push((
|
||||
Inst::VecMisc {
|
||||
op: VecMisc2::Frintm,
|
||||
rd: writable_vreg(12),
|
||||
rn: vreg(17),
|
||||
size: VectorSize::Size64x2,
|
||||
},
|
||||
"2C9A614E",
|
||||
"frintm v12.2d, v17.2d",
|
||||
));
|
||||
|
||||
insns.push((
|
||||
Inst::VecMisc {
|
||||
op: VecMisc2::Frintp,
|
||||
rd: writable_vreg(11),
|
||||
rn: vreg(18),
|
||||
size: VectorSize::Size32x4,
|
||||
},
|
||||
"4B8AA14E",
|
||||
"frintp v11.4s, v18.4s",
|
||||
));
|
||||
|
||||
insns.push((
|
||||
Inst::VecMisc {
|
||||
op: VecMisc2::Frintp,
|
||||
rd: writable_vreg(12),
|
||||
rn: vreg(17),
|
||||
size: VectorSize::Size64x2,
|
||||
},
|
||||
"2C8AE14E",
|
||||
"frintp v12.2d, v17.2d",
|
||||
));
|
||||
|
||||
insns.push((
|
||||
Inst::VecLanes {
|
||||
op: VecLanesOp::Uminv,
|
||||
|
||||
@@ -319,6 +319,14 @@ pub enum VecMisc2 {
|
||||
Scvtf,
|
||||
/// Unsigned integer convert to floating-point
|
||||
Ucvtf,
|
||||
/// Floating point round to integral, rounding towards nearest
|
||||
Frintn,
|
||||
/// Floating point round to integral, rounding towards zero
|
||||
Frintz,
|
||||
/// Floating point round to integral, rounding towards minus infinity
|
||||
Frintm,
|
||||
/// Floating point round to integral, rounding towards plus infinity
|
||||
Frintp,
|
||||
}
|
||||
|
||||
/// A Vector narrowing operation with two registers.
|
||||
@@ -3436,6 +3444,10 @@ impl Inst {
|
||||
VecMisc2::Fcvtzu => ("fcvtzu", size),
|
||||
VecMisc2::Scvtf => ("scvtf", size),
|
||||
VecMisc2::Ucvtf => ("ucvtf", size),
|
||||
VecMisc2::Frintn => ("frintn", size),
|
||||
VecMisc2::Frintz => ("frintz", size),
|
||||
VecMisc2::Frintm => ("frintm", size),
|
||||
VecMisc2::Frintp => ("frintp", size),
|
||||
};
|
||||
|
||||
let rd_size = if is_shll { size.widen() } else { size };
|
||||
|
||||
Reference in New Issue
Block a user