From c56fd204c62b5390dc019a72010b6eb881e04260 Mon Sep 17 00:00:00 2001 From: Opstic <46141527+opstic@users.noreply.github.com> Date: Sat, 13 Dec 2025 03:59:13 -0500 Subject: [PATCH 1/3] Add `llvm.x86.vcvtps2ph.128` --- src/intrinsics/llvm_x86.rs | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/intrinsics/llvm_x86.rs b/src/intrinsics/llvm_x86.rs index 37fbe4be1..9360965fd 100644 --- a/src/intrinsics/llvm_x86.rs +++ b/src/intrinsics/llvm_x86.rs @@ -1313,6 +1313,35 @@ pub(super) fn codegen_x86_llvm_intrinsic_call<'tcx>( ret.write_cvalue_transmute(fx, res); } + "llvm.x86.vcvtps2ph.128" => { + // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cvtps_ph + intrinsic_args!(fx, args => (a, _imm8); intrinsic); + let a = a.load_scalar(fx); + + let imm8 = + if let Some(imm8) = crate::constant::mir_operand_get_const_val(fx, &args[1].node) { + imm8 + } else { + fx.tcx + .dcx() + .span_fatal(span, "Index argument for `_mm_cvtps_ph` is not a constant"); + }; + + let imm8 = imm8.to_u32(); + + codegen_inline_asm_inner( + fx, + &[InlineAsmTemplatePiece::String(format!("vcvtps2ph xmm0, xmm0, {imm8}").into())], + &[CInlineAsmOperand::InOut { + reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm0)), + _late: true, + in_value: a, + out_place: Some(ret) + }], + InlineAsmOptions::NOSTACK | InlineAsmOptions::PURE | InlineAsmOptions::NOMEM, + ); + } + _ => { fx.tcx .dcx() From c437c3a83f05605c8c8f4c5367ced14064d85d29 Mon Sep 17 00:00:00 2001 From: Opstic <46141527+opstic@users.noreply.github.com> Date: Sat, 13 Dec 2025 04:06:44 -0500 Subject: [PATCH 2/3] `cargo fmt` --- src/intrinsics/llvm_x86.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/intrinsics/llvm_x86.rs b/src/intrinsics/llvm_x86.rs index 9360965fd..61f48fa97 100644 --- a/src/intrinsics/llvm_x86.rs +++ b/src/intrinsics/llvm_x86.rs @@ -1336,7 +1336,7 @@ pub(super) fn codegen_x86_llvm_intrinsic_call<'tcx>( reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm0)), _late: true, in_value: a, - out_place: Some(ret) + out_place: Some(ret), }], InlineAsmOptions::NOSTACK | InlineAsmOptions::PURE | InlineAsmOptions::NOMEM, ); From d6a7e7879b52491f402ae11d169b55eb51301c7f Mon Sep 17 00:00:00 2001 From: Opstic <46141527+opstic@users.noreply.github.com> Date: Sun, 14 Dec 2025 00:24:56 -0500 Subject: [PATCH 3/3] Test `_mm_cvtps_ph` --- example/std_example.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/example/std_example.rs b/example/std_example.rs index c569ef0ef..33db75f09 100644 --- a/example/std_example.rs +++ b/example/std_example.rs @@ -259,6 +259,9 @@ unsafe fn test_simd() { test_mm_cvttps_epi32(); test_mm_cvtsi128_si64(); + #[cfg(not(jit))] + test_mm_cvtps_ph(); + test_mm_extract_epi8(); test_mm_insert_epi16(); test_mm_shuffle_epi8(); @@ -558,6 +561,21 @@ unsafe fn test_mm_cvttps_epi32() { } } +#[cfg(target_arch = "x86_64")] +#[target_feature(enable = "f16c")] +#[cfg(not(jit))] +unsafe fn test_mm_cvtps_ph() { + const F16_ONE: i16 = 0x3c00; + const F16_TWO: i16 = 0x4000; + const F16_THREE: i16 = 0x4200; + const F16_FOUR: i16 = 0x4400; + + let a = _mm_set_ps(1.0, 2.0, 3.0, 4.0); + let r = _mm_cvtps_ph::<_MM_FROUND_CUR_DIRECTION>(a); + let e = _mm_set_epi16(0, 0, 0, 0, F16_ONE, F16_TWO, F16_THREE, F16_FOUR); + assert_eq_m128i(r, e); +} + fn test_checked_mul() { let u: Option = u8::from_str_radix("1000", 10).ok(); assert_eq!(u, None);