diff --git a/cranelift/codegen/meta/src/isa/x86/encodings.rs b/cranelift/codegen/meta/src/isa/x86/encodings.rs index 2ae60896d4..4a04ef574d 100644 --- a/cranelift/codegen/meta/src/isa/x86/encodings.rs +++ b/cranelift/codegen/meta/src/isa/x86/encodings.rs @@ -234,7 +234,7 @@ impl PerCpuModeEncodings { } fn enc_both_isap( &mut self, - inst: BoundInstruction, + inst: impl Clone + Into, template: Template, isap: SettingPredicateNumber, ) { @@ -243,7 +243,7 @@ impl PerCpuModeEncodings { } fn enc_both_instp( &mut self, - inst: BoundInstruction, + inst: impl Clone + Into, template: Template, 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 - for ty in ValueType::all_lane_types().filter(|t| t.lane_bits() == 8) { - let instruction = bitcast.bind_vector_from_lane(ty, sse_vector_size).bind(F64); + // helper for generating null encodings for FPRs on both 32- and 64-bit architectures + let mut null_encode_32_64 = |instruction: BoundInstruction| { e.enc32_rec(instruction.clone(), 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) for from_type in ValueType::all_lane_types().filter(allowed_simd_type) { for to_type in ValueType::all_lane_types().filter(|t| allowed_simd_type(t) && *t != from_type) { - let instruction = raw_bitcast - .bind_vector_from_lane(to_type, sse_vector_size) - .bind_vector_from_lane(from_type, sse_vector_size); - e.enc32_rec(instruction.clone(), rec_null_fpr, 0); - e.enc64_rec(instruction, rec_null_fpr, 0); + null_encode_32_64( + raw_bitcast + .bind_vector_from_lane(to_type, sse_vector_size) + .bind_vector_from_lane(from_type, sse_vector_size), + ); + } + } + + // 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), + ); } } diff --git a/cranelift/codegen/meta/src/isa/x86/legalize.rs b/cranelift/codegen/meta/src/isa/x86/legalize.rs index 2fd160de3a..d56beb8022 100644 --- a/cranelift/codegen/meta/src/isa/x86/legalize.rs +++ b/cranelift/codegen/meta/src/isa/x86/legalize.rs @@ -20,7 +20,6 @@ pub(crate) fn define(shared: &mut SharedDefinitions, x86_instructions: &Instruct // List of instructions. let insts = &shared.instructions; let band = insts.by_name("band"); - let bitcast = insts.by_name("bitcast"); let bor = insts.by_name("bor"); let clz = insts.by_name("clz"); let ctz = insts.by_name("ctz"); @@ -321,7 +320,9 @@ pub(crate) fn define(shared: &mut SharedDefinitions, x86_instructions: &Instruct // SIMD splat: 8-bits 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 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( def!(y = splat_any8x16(x)), vec![ diff --git a/cranelift/filetests/filetests/isa/x86/legalize-splat.clif b/cranelift/filetests/filetests/isa/x86/legalize-splat.clif index fa07f80c11..c0fc83ebe7 100644 --- a/cranelift/filetests/filetests/isa/x86/legalize-splat.clif +++ b/cranelift/filetests/filetests/isa/x86/legalize-splat.clif @@ -68,6 +68,6 @@ ebb0: ; nextln: v0 = ireduce.i8 v2 ; nextln: v3 = scalar_to_vector.i8x16 v0 ; nextln: v4 = f64const 0.0 -; nextln: v5 = bitcast.i8x16 v4 +; nextln: v5 = raw_bitcast.i8x16 v4 ; nextln: v1 = x86_pshufb v3, v5 ; nextln: return v1