diff --git a/Cargo.lock b/Cargo.lock index ab2c7ca8a47c..2ce9eb081eec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -79,16 +79,16 @@ dependencies = [ [[package]] name = "gccjit" -version = "1.0.0" -source = "git+https://github.com/antoyo/gccjit.rs#9f8f67edc006d543b17529a001803ffece48349e" +version = "2.0.0" +source = "git+https://github.com/antoyo/gccjit.rs#f1545d7c2c13e42d78eaac8032d49ab8f7d43b6e" dependencies = [ "gccjit_sys", ] [[package]] name = "gccjit_sys" -version = "0.0.1" -source = "git+https://github.com/antoyo/gccjit.rs#9f8f67edc006d543b17529a001803ffece48349e" +version = "0.1.0" +source = "git+https://github.com/antoyo/gccjit.rs#f1545d7c2c13e42d78eaac8032d49ab8f7d43b6e" dependencies = [ "libc", ] diff --git a/libgccjit.version b/libgccjit.version index 41bec6df5d95..adf9b64c826f 100644 --- a/libgccjit.version +++ b/libgccjit.version @@ -1 +1 @@ -b6f163f52 +ac1853f579dbfdc53f2c22317e673ae99686eca2 diff --git a/src/builder.rs b/src/builder.rs index e9c16a0e4a71..30343f2e17b4 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -748,6 +748,24 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { // FIXME(antoyo): this seems to produce the wrong result. return self.context.new_call(self.location, fmodf, &[a, b]); } + + #[cfg(feature = "master")] + match self.cx.type_kind(a_type) { + TypeKind::Half | TypeKind::Float => { + let fmodf = self.context.get_builtin_function("fmodf"); + return self.context.new_call(self.location, fmodf, &[a, b]); + } + TypeKind::Double => { + let fmod = self.context.get_builtin_function("fmod"); + return self.context.new_call(self.location, fmod, &[a, b]); + } + TypeKind::FP128 => { + let fmodl = self.context.get_builtin_function("fmodl"); + return self.context.new_call(self.location, fmodl, &[a, b]); + } + _ => (), + } + if let Some(vector_type) = a_type_unqualified.dyncast_vector() { assert_eq!(a_type_unqualified, b.get_type().unqualified()); diff --git a/src/type_.rs b/src/type_.rs index d0d3c21f0cf0..cc26f306d6de 100644 --- a/src/type_.rs +++ b/src/type_.rs @@ -1,4 +1,6 @@ -use gccjit::{RValue, Struct, Type}; +use std::convert::TryInto; + +use gccjit::{CType, RValue, Struct, Type}; use rustc_codegen_ssa::common::TypeKind; use rustc_codegen_ssa::traits::{BaseTypeMethods, DerivedTypeMethods, TypeMembershipMethods}; use rustc_middle::ty::layout::TyAndLayout; @@ -120,10 +122,28 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { self.isize_type } + #[cfg(feature = "master")] fn type_f16(&self) -> Type<'gcc> { - unimplemented!("f16_f128") + if self.context.get_target_info().supports_target_dependent_type(CType::Float16) { + return self.context.new_c_type(CType::Float16); + } + unimplemented!("f16") } + #[cfg(not(feature = "master"))] + fn type_f16(&self) -> Type<'gcc> { + unimplemented!("f16") + } + + #[cfg(feature = "master")] + fn type_f32(&self) -> Type<'gcc> { + if self.context.get_target_info().supports_target_dependent_type(CType::Float32) { + return self.context.new_c_type(CType::Float32); + } + self.float_type + } + + #[cfg(not(feature = "master"))] fn type_f32(&self) -> Type<'gcc> { self.float_type } @@ -132,8 +152,17 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { self.double_type } + #[cfg(feature = "master")] fn type_f128(&self) -> Type<'gcc> { - unimplemented!("f16_f128") + if self.context.get_target_info().supports_target_dependent_type(CType::Float128) { + return self.context.new_c_type(CType::Float128); + } + unimplemented!("f128") + } + + #[cfg(not(feature = "master"))] + fn type_f128(&self) -> Type<'gcc> { + unimplemented!("f128") } fn type_func(&self, params: &[Type<'gcc>], return_type: Type<'gcc>) -> Type<'gcc> { @@ -161,6 +190,31 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { typ } + #[cfg(feature = "master")] + fn type_kind(&self, typ: Type<'gcc>) -> TypeKind { + if self.is_int_type_or_bool(typ) { + TypeKind::Integer + } else if typ.is_compatible_with(self.float_type) { + TypeKind::Float + } else if typ.is_compatible_with(self.double_type) { + TypeKind::Double + } else if typ.is_vector() { + TypeKind::Vector + } else if typ.is_floating_point() { + match typ.get_size() { + 2 => TypeKind::Half, + 4 => TypeKind::Float, + 8 => TypeKind::Double, + 16 => TypeKind::FP128, + _ => TypeKind::Void, + } + } else { + // TODO(antoyo): support other types. + TypeKind::Void + } + } + + #[cfg(not(feature = "master"))] fn type_kind(&self, typ: Type<'gcc>) -> TypeKind { if self.is_int_type_or_bool(typ) { TypeKind::Integer @@ -210,6 +264,16 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { unimplemented!(); } + #[cfg(feature = "master")] + fn float_width(&self, typ: Type<'gcc>) -> usize { + if typ.is_floating_point() { + (typ.get_size() * u8::BITS).try_into().unwrap() + } else { + panic!("Cannot get width of float type {:?}", typ); + } + } + + #[cfg(not(feature = "master"))] fn float_width(&self, typ: Type<'gcc>) -> usize { let f32 = self.context.new_type::(); let f64 = self.context.new_type::();