libm: Add `frexpf16`

The new algorithm now correctly supports the type.
diff --git a/library/compiler-builtins/crates/libm-macros/src/shared.rs b/library/compiler-builtins/crates/libm-macros/src/shared.rs
index 5a5eca6..ee1feed 100644
--- a/library/compiler-builtins/crates/libm-macros/src/shared.rs
+++ b/library/compiler-builtins/crates/libm-macros/src/shared.rs
@@ -418,6 +418,20 @@ struct NestedOp {
         public: true,
     },
     NestedOp {
+        // `(f16, &mut c_int) -> f16` as `(f16) -> (f16, i32)`
+        float_ty: FloatTy::F16,
+        rust_sig: Signature {
+            args: &[Ty::F16],
+            returns: &[Ty::F16, Ty::I32],
+        },
+        c_sig: Some(Signature {
+            args: &[Ty::F16, Ty::MutCInt],
+            returns: &[Ty::F16],
+        }),
+        fn_list: &["frexpf16"],
+        public: true,
+    },
+    NestedOp {
         // `(f32, &mut c_int) -> f32` as `(f32) -> (f32, i32)`
         float_ty: FloatTy::F32,
         rust_sig: Signature {
diff --git a/library/compiler-builtins/etc/function-definitions.json b/library/compiler-builtins/etc/function-definitions.json
index 06eb1ad..6bd395a 100644
--- a/library/compiler-builtins/etc/function-definitions.json
+++ b/library/compiler-builtins/etc/function-definitions.json
@@ -579,6 +579,13 @@
         ],
         "type": "f128"
     },
+    "frexpf16": {
+        "sources": [
+            "libm/src/math/frexp.rs",
+            "libm/src/math/generic/frexp.rs"
+        ],
+        "type": "f16"
+    },
     "hypot": {
         "sources": [
             "libm/src/math/hypot.rs"
diff --git a/library/compiler-builtins/etc/function-list.txt b/library/compiler-builtins/etc/function-list.txt
index 45a39e3..f7a694d 100644
--- a/library/compiler-builtins/etc/function-list.txt
+++ b/library/compiler-builtins/etc/function-list.txt
@@ -85,6 +85,7 @@
 frexp
 frexpf
 frexpf128
+frexpf16
 hypot
 hypotf
 ilogb
diff --git a/library/compiler-builtins/libm-test/benches/icount.rs b/library/compiler-builtins/libm-test/benches/icount.rs
index be5178e..617e9fb 100644
--- a/library/compiler-builtins/libm-test/benches/icount.rs
+++ b/library/compiler-builtins/libm-test/benches/icount.rs
@@ -332,6 +332,7 @@ fn icount_bench_print_hf128(x: f128) -> String {
     icount_bench_fmodf_group,
     icount_bench_frexp_group,
     icount_bench_frexpf128_group,
+    icount_bench_frexpf16_group,
     icount_bench_frexpf_group,
     icount_bench_hypot_group,
     icount_bench_hypotf_group,
diff --git a/library/compiler-builtins/libm-test/src/generate/case_list.rs b/library/compiler-builtins/libm-test/src/generate/case_list.rs
index 958e03a..66d7f6a 100644
--- a/library/compiler-builtins/libm-test/src/generate/case_list.rs
+++ b/library/compiler-builtins/libm-test/src/generate/case_list.rs
@@ -460,6 +460,11 @@ fn fmodf16_cases() -> Vec<TestCase<op::fmodf16::Routine>> {
     vec![]
 }
 
+#[cfg(f16_enabled)]
+fn frexpf16_cases() -> Vec<TestCase<op::frexpf16::Routine>> {
+    vec![]
+}
+
 fn frexpf_cases() -> Vec<TestCase<op::frexpf::Routine>> {
     vec![]
 }
diff --git a/library/compiler-builtins/libm-test/src/mpfloat.rs b/library/compiler-builtins/libm-test/src/mpfloat.rs
index 3237a23..91130f8 100644
--- a/library/compiler-builtins/libm-test/src/mpfloat.rs
+++ b/library/compiler-builtins/libm-test/src/mpfloat.rs
@@ -163,6 +163,7 @@ fn run(this: &mut Self::MpTy, input: Self::RustArgs) -> Self::RustRet {
         frexp,
         frexpf,
         frexpf128,
+        frexpf16,
         ilogb,
         ilogbf,
         ilogbf128,
@@ -327,20 +328,6 @@ fn run(this: &mut Self::MpTy, input: Self::RustArgs) -> Self::RustRet {
                 }
             }
 
-            impl MpOp for crate::op::[<frexp $suffix>]::Routine {
-                type MpTy = MpFloat;
-
-                fn new_mp() -> Self::MpTy {
-                    new_mpfloat::<Self::FTy>()
-                }
-
-                fn run(this: &mut Self::MpTy, input: Self::RustArgs) -> Self::RustRet {
-                    this.assign(input.0);
-                    let exp = this.frexp_mut();
-                    (prep_retval::<Self::FTy>(this, Ordering::Equal), exp)
-                }
-            }
-
             impl MpOp for crate::op::[<jn $suffix>]::Routine {
                 type MpTy = MpFloat;
 
@@ -485,6 +472,20 @@ fn run(this: &mut Self::MpTy, input: Self::RustArgs) -> Self::RustRet {
                 }
             }
 
+            impl MpOp for crate::op::[<frexp $suffix>]::Routine {
+                type MpTy = MpFloat;
+
+                fn new_mp() -> Self::MpTy {
+                    new_mpfloat::<Self::FTy>()
+                }
+
+                fn run(this: &mut Self::MpTy, input: Self::RustArgs) -> Self::RustRet {
+                    this.assign(input.0);
+                    let exp = this.frexp_mut();
+                    (prep_retval::<Self::FTy>(this, Ordering::Equal), exp)
+                }
+            }
+
             impl MpOp for crate::op::[<ilogb $suffix>]::Routine {
                 type MpTy = MpFloat;
 
@@ -549,21 +550,6 @@ fn run(this: &mut Self::MpTy, input: Self::RustArgs) -> Self::RustRet {
 #[cfg(f128_enabled)]
 impl_op_for_ty_all!(f128, "f128");
 
-#[cfg(f128_enabled)]
-impl MpOp for crate::op::frexpf128::Routine {
-    type MpTy = MpFloat;
-
-    fn new_mp() -> Self::MpTy {
-        new_mpfloat::<Self::FTy>()
-    }
-
-    fn run(this: &mut Self::MpTy, input: Self::RustArgs) -> Self::RustRet {
-        this.assign(input.0);
-        let exp = this.frexp_mut();
-        (prep_retval::<Self::FTy>(this, Ordering::Equal), exp)
-    }
-}
-
 // `lgamma_r` is not a simple suffix so we can't use the above macro.
 impl MpOp for crate::op::lgamma_r::Routine {
     type MpTy = MpFloat;
diff --git a/library/compiler-builtins/libm/src/math/frexp.rs b/library/compiler-builtins/libm/src/math/frexp.rs
index f2f545f..af38915 100644
--- a/library/compiler-builtins/libm/src/math/frexp.rs
+++ b/library/compiler-builtins/libm/src/math/frexp.rs
@@ -2,11 +2,10 @@
 ///
 /// That is, `x * 2^p` will represent the input value.
 // Placeholder so we can have `frexpf16` in the `Float` trait.
-#[allow(unused)]
 #[cfg(f16_enabled)]
 #[cfg_attr(assert_no_panic, no_panic::no_panic)]
-pub(crate) fn frexpf16(x: f16) -> (f16, i32) {
-    unimplemented!()
+pub fn frexpf16(x: f16) -> (f16, i32) {
+    super::generic::frexp(x)
 }
 
 /// Decompose a float into a normalized value within the range `[0.5, 1)`, and a power of 2.
diff --git a/library/compiler-builtins/libm/src/math/mod.rs b/library/compiler-builtins/libm/src/math/mod.rs
index 0484fe6..b34ab84 100644
--- a/library/compiler-builtins/libm/src/math/mod.rs
+++ b/library/compiler-builtins/libm/src/math/mod.rs
@@ -322,6 +322,7 @@ macro_rules! div {
         pub use self::fminimum_fmaximum::{fmaximumf16, fminimumf16};
         pub use self::fminimum_fmaximum_num::{fmaximum_numf16, fminimum_numf16};
         pub use self::fmod::fmodf16;
+        pub use self::frexp::frexpf16;
         pub use self::ilogb::ilogbf16;
         pub use self::ldexp::ldexpf16;
         pub use self::rint::rintf16;
@@ -334,9 +335,6 @@ macro_rules! div {
 
         #[allow(unused_imports)]
         pub(crate) use self::fma::fmaf16;
-
-        #[allow(unused_imports)]
-        pub(crate) use self::frexp::frexpf16;
     }
 }