diff --git a/cranelift/codegen/meta/src/isa/x86/encodings.rs b/cranelift/codegen/meta/src/isa/x86/encodings.rs index 0f2a96cc93..e496511e7c 100644 --- a/cranelift/codegen/meta/src/isa/x86/encodings.rs +++ b/cranelift/codegen/meta/src/isa/x86/encodings.rs @@ -1568,6 +1568,7 @@ fn define_simd( let copy_nop = shared.by_name("copy_nop"); let fadd = shared.by_name("fadd"); let fcmp = shared.by_name("fcmp"); + let fcvt_from_sint = shared.by_name("fcvt_from_sint"); let fdiv = shared.by_name("fdiv"); let fill = shared.by_name("fill"); let fill_nop = shared.by_name("fill_nop"); @@ -1790,6 +1791,14 @@ fn define_simd( } } + // SIMD conversions + { + let fcvt_from_sint_32 = fcvt_from_sint + .bind(vector(F32, sse_vector_size)) + .bind(vector(I32, sse_vector_size)); + e.enc_both(fcvt_from_sint_32, rec_furm.opcodes(&CVTDQ2PS)); + } + // SIMD vconst for special cases (all zeroes, all ones) // this must be encoded prior to the MOVUPS implementation (below) so the compiler sees this // encoding first diff --git a/cranelift/codegen/meta/src/isa/x86/opcodes.rs b/cranelift/codegen/meta/src/isa/x86/opcodes.rs index 52999e75e0..1a895fe2ec 100644 --- a/cranelift/codegen/meta/src/isa/x86/opcodes.rs +++ b/cranelift/codegen/meta/src/isa/x86/opcodes.rs @@ -77,6 +77,10 @@ pub static CMPPD: [u8; 3] = [0x66, 0x0f, 0xc2]; /// imm8 as comparison predicate (SSE). pub static CMPPS: [u8; 2] = [0x0f, 0xc2]; +/// Convert four packed signed doubleword integers from xmm2/mem to four packed single-precision +/// floating-point values in xmm1 (SSE2). +pub static CVTDQ2PS: [u8; 2] = [0x0f, 0x5b]; + /// Convert scalar double-precision floating-point value to scalar single-precision /// floating-point value. pub static CVTSD2SS: [u8; 3] = [0xf2, 0x0f, 0x5a]; diff --git a/cranelift/filetests/filetests/isa/x86/simd-conversion-binemit.clif b/cranelift/filetests/filetests/isa/x86/simd-conversion-binemit.clif index 3e91ea0ec3..ae1cdda753 100644 --- a/cranelift/filetests/filetests/isa/x86/simd-conversion-binemit.clif +++ b/cranelift/filetests/filetests/isa/x86/simd-conversion-binemit.clif @@ -9,3 +9,9 @@ block0: [-, %xmm2] v2 = raw_bitcast.i32x4 v1 ; bin: return } + +function %fcvt_32(i32x4) { +block0(v0: i32x4 [%xmm6]): +[-, %xmm2] v1 = fcvt_from_sint.f32x4 v0 ; bin: 40 0f 5b d6 + return +} diff --git a/cranelift/filetests/filetests/isa/x86/simd-conversion-run.clif b/cranelift/filetests/filetests/isa/x86/simd-conversion-run.clif new file mode 100644 index 0000000000..6968f18dbb --- /dev/null +++ b/cranelift/filetests/filetests/isa/x86/simd-conversion-run.clif @@ -0,0 +1,14 @@ +test run +set enable_simd + +function %fcvt_from_sint() -> b1 { +block0: + v0 = vconst.i32x4 [-1 0 1 123456789] + v1 = fcvt_from_sint.f32x4 v0 + + v2 = vconst.f32x4 [-0x1.0 0.0 0x1.0 0x75bcd18.0] ; 123456789 rounds to 123456792.0, an error of 3 + v3 = fcmp eq v1, v2 + v4 = vall_true v3 + return v4 +} +; run