Add x86 implementation of shuffle
This commit is contained in:
@@ -1785,7 +1785,7 @@ pub(crate) fn define(
|
||||
let allowed_simd_type = |t: &LaneType| t.lane_bits() >= 8 && t.lane_bits() < 128;
|
||||
|
||||
// PSHUFB, 8-bit shuffle using two XMM registers.
|
||||
for ty in ValueType::all_lane_types().filter(|t| t.lane_bits() == 8) {
|
||||
for ty in ValueType::all_lane_types().filter(allowed_simd_type) {
|
||||
let instruction = x86_pshufb.bind_vector_from_lane(ty, sse_vector_size);
|
||||
let template = rec_fa.nonrex().opcodes(vec![0x66, 0x0f, 0x38, 00]);
|
||||
e.enc32_isap(instruction.clone(), template.clone(), use_ssse3_simd);
|
||||
@@ -1804,7 +1804,7 @@ pub(crate) fn define(
|
||||
|
||||
// SIMD scalar_to_vector; this uses MOV to copy the scalar value to an XMM register; according
|
||||
// to the Intel manual: "When the destination operand is an XMM register, the source operand is
|
||||
// written to the low doubleword of the register and the regiser is zero-extended to 128 bits."
|
||||
// written to the low doubleword of the register and the register is zero-extended to 128 bits."
|
||||
for ty in ValueType::all_lane_types().filter(allowed_simd_type) {
|
||||
let instruction = scalar_to_vector.bind_vector_from_lane(ty, sse_vector_size);
|
||||
if ty.is_float() {
|
||||
@@ -1929,6 +1929,13 @@ pub(crate) fn define(
|
||||
e.enc_32_64_maybe_isap(instruction, template, None); // from SSE
|
||||
}
|
||||
|
||||
// SIMD bor using ORPS
|
||||
for ty in ValueType::all_lane_types().filter(allowed_simd_type) {
|
||||
let instruction = bor.bind_vector_from_lane(ty, sse_vector_size);
|
||||
let template = rec_fa.nonrex().opcodes(vec![0x0f, 0x56]);
|
||||
e.enc_32_64_maybe_isap(instruction, template, None); // from SSE
|
||||
}
|
||||
|
||||
// Reference type instructions
|
||||
|
||||
// Null references implemented as iconst 0.
|
||||
|
||||
@@ -45,6 +45,7 @@ pub(crate) fn define(shared: &mut SharedDefinitions, x86_instructions: &Instruct
|
||||
let selectif = insts.by_name("selectif");
|
||||
let smulhi = insts.by_name("smulhi");
|
||||
let splat = insts.by_name("splat");
|
||||
let shuffle = insts.by_name("shuffle");
|
||||
let srem = insts.by_name("srem");
|
||||
let udiv = insts.by_name("udiv");
|
||||
let umulhi = insts.by_name("umulhi");
|
||||
@@ -380,6 +381,7 @@ pub(crate) fn define(shared: &mut SharedDefinitions, x86_instructions: &Instruct
|
||||
);
|
||||
}
|
||||
|
||||
narrow.custom_legalize(shuffle, "convert_shuffle");
|
||||
narrow.custom_legalize(extractlane, "convert_extractlane");
|
||||
narrow.custom_legalize(insertlane, "convert_insertlane");
|
||||
|
||||
|
||||
@@ -396,11 +396,11 @@ pub(crate) fn define<'shared>(
|
||||
let f_trap = formats.by_name("Trap");
|
||||
let f_unary = formats.by_name("Unary");
|
||||
let f_unary_bool = formats.by_name("UnaryBool");
|
||||
let f_unary_const = formats.by_name("UnaryConst");
|
||||
let f_unary_global_value = formats.by_name("UnaryGlobalValue");
|
||||
let f_unary_ieee32 = formats.by_name("UnaryIeee32");
|
||||
let f_unary_ieee64 = formats.by_name("UnaryIeee64");
|
||||
let f_unary_imm = formats.by_name("UnaryImm");
|
||||
let f_unary_imm128 = formats.by_name("UnaryImm128");
|
||||
|
||||
// Predicates shorthands.
|
||||
let use_sse41 = settings.predicate_by_name("use_sse41");
|
||||
@@ -2437,14 +2437,14 @@ pub(crate) fn define<'shared>(
|
||||
);
|
||||
|
||||
recipes.add_template_recipe(
|
||||
EncodingRecipeBuilder::new("vconst", f_unary_imm128, 5)
|
||||
EncodingRecipeBuilder::new("vconst", f_unary_const, 5)
|
||||
.operands_out(vec![fpr])
|
||||
.clobbers_flags(false)
|
||||
.emit(
|
||||
r#"
|
||||
{{PUT_OP}}(bits, rex2(0, out_reg0), sink);
|
||||
modrm_riprel(out_reg0, sink);
|
||||
const_disp4(imm, func, sink);
|
||||
const_disp4(constant_handle, func, sink);
|
||||
"#,
|
||||
),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user