Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support float16 #2667

Merged
merged 1 commit into from
Dec 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions bindgen-tests/tests/expectations/tests/float16.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 36 additions & 0 deletions bindgen-tests/tests/headers/float16.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// bindgen-flags: --with-derive-hash --with-derive-partialeq --with-derive-eq

static __fp16 global;

struct Test__Float16
{
__fp16 f;
};

struct Test__Float16Ref
{
__fp16 *f;
};

/*
// This options are currently supported only on specific targets (eg. x86 with sse2)
_Float16 returns_f16();

void gets_f16(_Float16 arg);

struct Test__Float16_Complex
{
_Float16 _Complex mMember;
};

struct Test__Float16_ComplexPtr
{
_Float16 _Complex *mMember;
};

_Float16 _Complex globalValueHalf;

_Float16 _Complex returns_f16_complex();

void gets_f16_complex(_Float16 _Complex arg);
*/
9 changes: 9 additions & 0 deletions bindgen/codegen/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,15 @@ pub(crate) mod ast_ty {
//
// Also, maybe this one shouldn't be the default?
match (fk, ctx.options().convert_floats) {
(FloatKind::Float16, _) => {
// TODO: do f16 when rust lands it
ctx.generated_bindgen_float16();
if ctx.options().enable_cxx_namespaces {
syn::parse_quote! { root::__BindgenFloat16 }
} else {
syn::parse_quote! { __BindgenFloat16 }
}
}
(FloatKind::Float, true) => syn::parse_quote! { f32 },
(FloatKind::Double, true) => syn::parse_quote! { f64 },
(FloatKind::Float, false) => raw_type(ctx, "c_float"),
Expand Down
17 changes: 17 additions & 0 deletions bindgen/codegen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,9 @@ impl CodeGenerator for Module {
if result.saw_incomplete_array {
utils::prepend_incomplete_array_types(ctx, &mut *result);
}
if ctx.need_bindgen_float16_type() {
utils::prepend_float16_type(&mut *result);
}
if ctx.need_bindgen_complex_type() {
utils::prepend_complex_type(&mut *result);
}
Expand Down Expand Up @@ -5136,6 +5139,20 @@ pub(crate) mod utils {
result.extend(old_items);
}

pub(crate) fn prepend_float16_type(
result: &mut Vec<proc_macro2::TokenStream>,
) {
let float16_type = quote! {
#[derive(PartialEq, Copy, Clone, Hash, Debug, Default)]
#[repr(transparent)]
pub struct __BindgenFloat16(pub u16);
};

let items = vec![float16_type];
let old_items = mem::replace(result, items);
result.extend(old_items);
}

pub(crate) fn prepend_complex_type(
result: &mut Vec<proc_macro2::TokenStream>,
) {
Expand Down
2 changes: 2 additions & 0 deletions bindgen/codegen/serialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ impl<'a> CSerialize<'a> for Type {
write!(writer, "const ")?;
}
match float_kind {
FloatKind::Float16 => write!(writer, "_Float16")?,
FloatKind::Float => write!(writer, "float")?,
FloatKind::Double => write!(writer, "double")?,
FloatKind::LongDouble => write!(writer, "long double")?,
Expand All @@ -281,6 +282,7 @@ impl<'a> CSerialize<'a> for Type {
write!(writer, "const ")?;
}
match float_kind {
FloatKind::Float16 => write!(writer, "_Float16 complex")?,
FloatKind::Float => write!(writer, "float complex")?,
FloatKind::Double => write!(writer, "double complex")?,
FloatKind::LongDouble => {
Expand Down
16 changes: 16 additions & 0 deletions bindgen/ir/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,9 @@ pub(crate) struct BindgenContext {
/// Whether a bindgen complex was generated
generated_bindgen_complex: Cell<bool>,

/// Whether a bindgen float16 was generated
generated_bindgen_float16: Cell<bool>,

/// The set of `ItemId`s that are allowlisted. This the very first thing
/// computed after parsing our IR, and before running any of our analyses.
allowlisted: Option<ItemSet>,
Expand Down Expand Up @@ -585,6 +588,7 @@ If you encounter an error missing from this list, please file an issue or a PR!"
target_info,
options,
generated_bindgen_complex: Cell::new(false),
generated_bindgen_float16: Cell::new(false),
allowlisted: None,
blocklisted_types_implement_traits: Default::default(),
codegen_items: None,
Expand Down Expand Up @@ -2005,6 +2009,7 @@ If you encounter an error missing from this list, please file an issue or a PR!"
CXType_ULongLong => TypeKind::Int(IntKind::ULongLong),
CXType_Int128 => TypeKind::Int(IntKind::I128),
CXType_UInt128 => TypeKind::Int(IntKind::U128),
CXType_Float16 | CXType_Half => TypeKind::Float(FloatKind::Float16),
CXType_Float => TypeKind::Float(FloatKind::Float),
CXType_Double => TypeKind::Float(FloatKind::Double),
CXType_LongDouble => TypeKind::Float(FloatKind::LongDouble),
Expand All @@ -2013,6 +2018,7 @@ If you encounter an error missing from this list, please file an issue or a PR!"
let float_type =
ty.elem_type().expect("Not able to resolve complex type?");
let float_kind = match float_type.kind() {
CXType_Float16 | CXType_Half => FloatKind::Float16,
CXType_Float => FloatKind::Float,
CXType_Double => FloatKind::Double,
CXType_LongDouble => FloatKind::LongDouble,
Expand Down Expand Up @@ -2528,6 +2534,16 @@ If you encounter an error missing from this list, please file an issue or a PR!"
self.generated_bindgen_complex.get()
}

/// Call if a bindgen float16 is generated
pub(crate) fn generated_bindgen_float16(&self) {
self.generated_bindgen_float16.set(true)
}

/// Whether we need to generate the bindgen float16 type
pub(crate) fn need_bindgen_float16_type(&self) -> bool {
self.generated_bindgen_float16.get()
}

/// Compute which `enum`s have an associated `typedef` definition.
fn compute_enum_typedef_combos(&mut self) {
let _t = self.timer("compute_enum_typedef_combos");
Expand Down
2 changes: 2 additions & 0 deletions bindgen/ir/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,8 @@ impl TemplateParameters for TypeKind {
/// The kind of float this type represents.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub(crate) enum FloatKind {
/// A half (`_Float16` or `__fp16`)
Float16,
/// A `float`.
Float,
/// A `double`.
Expand Down
Loading