Use raw_bitcast when legalizing splat
raw_bitcast matches the intent of this legalization more clearly (to simply change the CLIF type without changing any bits) and the additional null encodings added are necessary for later instructions
This commit is contained in:
@@ -234,7 +234,7 @@ impl PerCpuModeEncodings {
|
|||||||
}
|
}
|
||||||
fn enc_both_isap(
|
fn enc_both_isap(
|
||||||
&mut self,
|
&mut self,
|
||||||
inst: BoundInstruction,
|
inst: impl Clone + Into<InstSpec>,
|
||||||
template: Template,
|
template: Template,
|
||||||
isap: SettingPredicateNumber,
|
isap: SettingPredicateNumber,
|
||||||
) {
|
) {
|
||||||
@@ -243,7 +243,7 @@ impl PerCpuModeEncodings {
|
|||||||
}
|
}
|
||||||
fn enc_both_instp(
|
fn enc_both_instp(
|
||||||
&mut self,
|
&mut self,
|
||||||
inst: BoundInstruction,
|
inst: impl Clone + Into<InstSpec>,
|
||||||
template: Template,
|
template: Template,
|
||||||
instp: InstructionPredicateNode,
|
instp: InstructionPredicateNode,
|
||||||
) {
|
) {
|
||||||
@@ -1811,23 +1811,38 @@ pub(crate) fn define(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SIMD bitcast f64 to all 8-bit-lane vectors (for legalizing splat.x8x16); assumes that f64 is stored in an XMM register
|
// helper for generating null encodings for FPRs on both 32- and 64-bit architectures
|
||||||
for ty in ValueType::all_lane_types().filter(|t| t.lane_bits() == 8) {
|
let mut null_encode_32_64 = |instruction: BoundInstruction| {
|
||||||
let instruction = bitcast.bind_vector_from_lane(ty, sse_vector_size).bind(F64);
|
|
||||||
e.enc32_rec(instruction.clone(), rec_null_fpr, 0);
|
e.enc32_rec(instruction.clone(), rec_null_fpr, 0);
|
||||||
e.enc64_rec(instruction, rec_null_fpr, 0);
|
e.enc64_rec(instruction, rec_null_fpr, 0);
|
||||||
}
|
};
|
||||||
|
|
||||||
// SIMD bitcast all 128-bit vectors to each other (for legalizing splat.x16x8)
|
// SIMD bitcast all 128-bit vectors to each other (for legalizing splat.x16x8)
|
||||||
for from_type in ValueType::all_lane_types().filter(allowed_simd_type) {
|
for from_type in ValueType::all_lane_types().filter(allowed_simd_type) {
|
||||||
for to_type in
|
for to_type in
|
||||||
ValueType::all_lane_types().filter(|t| allowed_simd_type(t) && *t != from_type)
|
ValueType::all_lane_types().filter(|t| allowed_simd_type(t) && *t != from_type)
|
||||||
{
|
{
|
||||||
let instruction = raw_bitcast
|
null_encode_32_64(
|
||||||
.bind_vector_from_lane(to_type, sse_vector_size)
|
raw_bitcast
|
||||||
.bind_vector_from_lane(from_type, sse_vector_size);
|
.bind_vector_from_lane(to_type, sse_vector_size)
|
||||||
e.enc32_rec(instruction.clone(), rec_null_fpr, 0);
|
.bind_vector_from_lane(from_type, sse_vector_size),
|
||||||
e.enc64_rec(instruction, rec_null_fpr, 0);
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SIMD raw bitcast floats to vector (and back); assumes that floats are already stored in an XMM register
|
||||||
|
for float_type in &[F32, F64] {
|
||||||
|
for lane_type in ValueType::all_lane_types().filter(allowed_simd_type) {
|
||||||
|
null_encode_32_64(
|
||||||
|
raw_bitcast
|
||||||
|
.bind_vector_from_lane(lane_type, sse_vector_size)
|
||||||
|
.bind(*float_type),
|
||||||
|
);
|
||||||
|
null_encode_32_64(
|
||||||
|
raw_bitcast
|
||||||
|
.bind(*float_type)
|
||||||
|
.bind_vector_from_lane(lane_type, sse_vector_size),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ pub(crate) fn define(shared: &mut SharedDefinitions, x86_instructions: &Instruct
|
|||||||
// List of instructions.
|
// List of instructions.
|
||||||
let insts = &shared.instructions;
|
let insts = &shared.instructions;
|
||||||
let band = insts.by_name("band");
|
let band = insts.by_name("band");
|
||||||
let bitcast = insts.by_name("bitcast");
|
|
||||||
let bor = insts.by_name("bor");
|
let bor = insts.by_name("bor");
|
||||||
let clz = insts.by_name("clz");
|
let clz = insts.by_name("clz");
|
||||||
let ctz = insts.by_name("ctz");
|
let ctz = insts.by_name("ctz");
|
||||||
@@ -321,7 +320,9 @@ pub(crate) fn define(shared: &mut SharedDefinitions, x86_instructions: &Instruct
|
|||||||
// SIMD splat: 8-bits
|
// SIMD splat: 8-bits
|
||||||
for ty in ValueType::all_lane_types().filter(|t| t.lane_bits() == 8) {
|
for ty in ValueType::all_lane_types().filter(|t| t.lane_bits() == 8) {
|
||||||
let splat_any8x16 = splat.bind_vector_from_lane(ty, sse_vector_size);
|
let splat_any8x16 = splat.bind_vector_from_lane(ty, sse_vector_size);
|
||||||
let bitcast_f64_to_any8x16 = bitcast.bind_vector_from_lane(ty, sse_vector_size).bind(F64);
|
let bitcast_f64_to_any8x16 = raw_bitcast
|
||||||
|
.bind_vector_from_lane(ty, sse_vector_size)
|
||||||
|
.bind(F64);
|
||||||
narrow.legalize(
|
narrow.legalize(
|
||||||
def!(y = splat_any8x16(x)),
|
def!(y = splat_any8x16(x)),
|
||||||
vec![
|
vec![
|
||||||
|
|||||||
@@ -68,6 +68,6 @@ ebb0:
|
|||||||
; nextln: v0 = ireduce.i8 v2
|
; nextln: v0 = ireduce.i8 v2
|
||||||
; nextln: v3 = scalar_to_vector.i8x16 v0
|
; nextln: v3 = scalar_to_vector.i8x16 v0
|
||||||
; nextln: v4 = f64const 0.0
|
; nextln: v4 = f64const 0.0
|
||||||
; nextln: v5 = bitcast.i8x16 v4
|
; nextln: v5 = raw_bitcast.i8x16 v4
|
||||||
; nextln: v1 = x86_pshufb v3, v5
|
; nextln: v1 = x86_pshufb v3, v5
|
||||||
; nextln: return v1
|
; nextln: return v1
|
||||||
|
|||||||
Reference in New Issue
Block a user