Add x86 implementation of shuffle
This commit is contained in:
@@ -6,10 +6,10 @@ pub(crate) fn define(imm: &Immediates, entities: &EntityRefs) -> FormatRegistry
|
||||
|
||||
registry.insert(Builder::new("Unary").value());
|
||||
registry.insert(Builder::new("UnaryImm").imm(&imm.imm64));
|
||||
registry.insert(Builder::new("UnaryImm128").imm(&imm.uimm128));
|
||||
registry.insert(Builder::new("UnaryIeee32").imm(&imm.ieee32));
|
||||
registry.insert(Builder::new("UnaryIeee64").imm(&imm.ieee64));
|
||||
registry.insert(Builder::new("UnaryBool").imm(&imm.boolean));
|
||||
registry.insert(Builder::new("UnaryConst").imm(&imm.pool_constant));
|
||||
registry.insert(Builder::new("UnaryGlobalValue").imm(&entities.global_value));
|
||||
|
||||
registry.insert(Builder::new("Binary").value().value());
|
||||
@@ -43,6 +43,12 @@ pub(crate) fn define(imm: &Immediates, entities: &EntityRefs) -> FormatRegistry
|
||||
.value()
|
||||
.imm_with_name("lane", &imm.uimm8),
|
||||
);
|
||||
registry.insert(
|
||||
Builder::new("Shuffle")
|
||||
.value()
|
||||
.value()
|
||||
.imm_with_name("mask", &imm.uimm128),
|
||||
);
|
||||
|
||||
registry.insert(Builder::new("IntCompare").imm(&imm.intcc).value().value());
|
||||
registry.insert(
|
||||
|
||||
@@ -23,6 +23,12 @@ pub(crate) struct Immediates {
|
||||
/// const.
|
||||
pub uimm128: OperandKind,
|
||||
|
||||
/// A constant stored in the constant pool.
|
||||
///
|
||||
/// This operand is used to pass constants to instructions like vconst while storing the
|
||||
/// actual bytes in the constant pool.
|
||||
pub pool_constant: OperandKind,
|
||||
|
||||
/// A 32-bit immediate signed offset.
|
||||
///
|
||||
/// This is used to represent an immediate address offset in load/store instructions.
|
||||
@@ -84,6 +90,12 @@ impl Immediates {
|
||||
|
||||
uimm128: Builder::new_imm("uimm128")
|
||||
.doc("A 128-bit immediate unsigned integer.")
|
||||
.rust_type("ir::Immediate")
|
||||
.build(),
|
||||
|
||||
pool_constant: Builder::new_imm("poolConstant")
|
||||
.doc("A constant stored in the constant pool.")
|
||||
.default_member("constant_handle")
|
||||
.rust_type("ir::Constant")
|
||||
.build(),
|
||||
|
||||
|
||||
@@ -1090,7 +1090,7 @@ pub(crate) fn define(
|
||||
|
||||
let N = &operand_doc(
|
||||
"N",
|
||||
&imm.uimm128,
|
||||
&imm.pool_constant,
|
||||
"The 16 immediate bytes of a 128-bit vector",
|
||||
);
|
||||
let a = &operand_doc("a", TxN, "A constant vector value");
|
||||
@@ -1108,6 +1108,41 @@ pub(crate) fn define(
|
||||
.operands_out(vec![a]),
|
||||
);
|
||||
|
||||
let mask = &operand_doc(
|
||||
"mask",
|
||||
&imm.uimm128,
|
||||
"The 16 immediate bytes used for selecting the elements to shuffle",
|
||||
);
|
||||
let Tx16 = &TypeVar::new(
|
||||
"Tx16",
|
||||
"A SIMD vector with exactly 16 lanes of 8-bit values; eventually this may support other \
|
||||
lane counts and widths",
|
||||
TypeSetBuilder::new()
|
||||
.ints(8..8)
|
||||
.bools(8..8)
|
||||
.simd_lanes(16..16)
|
||||
.includes_scalars(false)
|
||||
.build(),
|
||||
);
|
||||
let a = &operand_doc("a", Tx16, "A vector value");
|
||||
let b = &operand_doc("b", Tx16, "A vector value");
|
||||
|
||||
ig.push(
|
||||
Inst::new(
|
||||
"shuffle",
|
||||
r#"
|
||||
SIMD vector shuffle.
|
||||
|
||||
Shuffle two vectors using the given immediate bytes. For each of the 16 bytes of the
|
||||
immediate, a value i of 0-15 selects the i-th element of the first vector and a value i of
|
||||
16-31 selects the (i-16)th element of the second vector. Immediate values outside of the
|
||||
0-31 range place a 0 in the resulting vector lane.
|
||||
"#,
|
||||
)
|
||||
.operands_in(vec![a, b, mask])
|
||||
.operands_out(vec![a]),
|
||||
);
|
||||
|
||||
let a = &operand_doc("a", Ref, "A constant reference null value");
|
||||
|
||||
ig.push(
|
||||
|
||||
Reference in New Issue
Block a user