about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock8
-rw-r--r--build_system/build_sysroot/Cargo.toml4
-rw-r--r--libgccjit.version2
-rw-r--r--src/base.rs21
-rw-r--r--src/builder.rs18
-rw-r--r--src/context.rs13
-rw-r--r--src/lib.rs12
-rw-r--r--src/type_.rs70
8 files changed, 136 insertions, 12 deletions
diff --git a/Cargo.lock b/Cargo.lock
index ab2c7ca8a47..2ce9eb081ee 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/build_system/build_sysroot/Cargo.toml b/build_system/build_sysroot/Cargo.toml
index 05503128f2a..e4669923623 100644
--- a/build_system/build_sysroot/Cargo.toml
+++ b/build_system/build_sysroot/Cargo.toml
@@ -6,7 +6,9 @@ resolver = "2"
 
 [dependencies]
 core = { path = "./sysroot_src/library/core" }
-compiler_builtins = "0.1"
+# TODO: after the sync, revert to using version 0.1.
+# compiler_builtins = "0.1"
+compiler_builtins = "=0.1.109"
 alloc = { path = "./sysroot_src/library/alloc" }
 std = { path = "./sysroot_src/library/std", features = ["panic_unwind", "backtrace"] }
 test = { path = "./sysroot_src/library/test" }
diff --git a/libgccjit.version b/libgccjit.version
index 41bec6df5d9..8cce7358321 100644
--- a/libgccjit.version
+++ b/libgccjit.version
@@ -1 +1 @@
-b6f163f52
+d61ce945badf4c9d8237a13ca135e3c46ad13be3
diff --git a/src/base.rs b/src/base.rs
index 79a29a1135a..e88fde8ebef 100644
--- a/src/base.rs
+++ b/src/base.rs
@@ -2,7 +2,7 @@ use std::collections::HashSet;
 use std::env;
 use std::time::Instant;
 
-use gccjit::{FunctionType, GlobalKind};
+use gccjit::{CType, FunctionType, GlobalKind};
 use rustc_codegen_ssa::base::maybe_create_entry_wrapper;
 use rustc_codegen_ssa::mono_item::MonoItemExt;
 use rustc_codegen_ssa::traits::DebugInfoMethods;
@@ -181,7 +181,24 @@ pub fn compile_codegen_unit(
         context.set_allow_unreachable_blocks(true);
 
         {
-            let cx = CodegenCx::new(&context, cgu, tcx, target_info.supports_128bit_int());
+            // TODO: to make it less error-prone (calling get_target_info() will add the flag
+            // -fsyntax-only), forbid the compilation when get_target_info() is called on a
+            // context.
+            let f16_type_supported = target_info.supports_target_dependent_type(CType::Float16);
+            let f32_type_supported = target_info.supports_target_dependent_type(CType::Float32);
+            let f64_type_supported = target_info.supports_target_dependent_type(CType::Float64);
+            let f128_type_supported = target_info.supports_target_dependent_type(CType::Float128);
+            // TODO: improve this to avoid passing that many arguments.
+            let cx = CodegenCx::new(
+                &context,
+                cgu,
+                tcx,
+                target_info.supports_128bit_int(),
+                f16_type_supported,
+                f32_type_supported,
+                f64_type_supported,
+                f128_type_supported,
+            );
 
             let mono_items = cgu.items_in_deterministic_order(tcx);
             for &(mono_item, data) in &mono_items {
diff --git a/src/builder.rs b/src/builder.rs
index e9c16a0e4a7..30343f2e17b 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/context.rs b/src/context.rs
index 890b4b15fc0..5ece10cc70d 100644
--- a/src/context.rs
+++ b/src/context.rs
@@ -68,6 +68,10 @@ pub struct CodegenCx<'gcc, 'tcx> {
     pub sizet_type: Type<'gcc>,
 
     pub supports_128bit_integers: bool,
+    pub supports_f16_type: bool,
+    pub supports_f32_type: bool,
+    pub supports_f64_type: bool,
+    pub supports_f128_type: bool,
 
     pub float_type: Type<'gcc>,
     pub double_type: Type<'gcc>,
@@ -125,11 +129,16 @@ pub struct CodegenCx<'gcc, 'tcx> {
 }
 
 impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
+    #[allow(clippy::too_many_arguments)]
     pub fn new(
         context: &'gcc Context<'gcc>,
         codegen_unit: &'tcx CodegenUnit<'tcx>,
         tcx: TyCtxt<'tcx>,
         supports_128bit_integers: bool,
+        supports_f16_type: bool,
+        supports_f32_type: bool,
+        supports_f64_type: bool,
+        supports_f128_type: bool,
     ) -> Self {
         let check_overflow = tcx.sess.overflow_checks();
 
@@ -305,6 +314,10 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
             sizet_type,
 
             supports_128bit_integers,
+            supports_f16_type,
+            supports_f32_type,
+            supports_f64_type,
+            supports_f128_type,
 
             float_type,
             double_type,
diff --git a/src/lib.rs b/src/lib.rs
index af110e3ab5e..9b9b97b9595 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -89,7 +89,6 @@ use std::sync::Arc;
 use std::sync::Mutex;
 
 use errors::LTONotSupported;
-#[cfg(not(feature = "master"))]
 use gccjit::CType;
 use gccjit::{Context, OptimizationLevel};
 #[cfg(feature = "master")]
@@ -147,6 +146,10 @@ impl TargetInfo {
     fn supports_128bit_int(&self) -> bool {
         self.supports_128bit_integers.load(Ordering::SeqCst)
     }
+
+    fn supports_target_dependent_type(&self, _typ: CType) -> bool {
+        false
+    }
 }
 
 #[derive(Clone)]
@@ -168,6 +171,10 @@ impl LockedTargetInfo {
     fn supports_128bit_int(&self) -> bool {
         self.info.lock().expect("lock").supports_128bit_int()
     }
+
+    fn supports_target_dependent_type(&self, typ: CType) -> bool {
+        self.info.lock().expect("lock").supports_target_dependent_type(typ)
+    }
 }
 
 #[derive(Clone)]
@@ -438,7 +445,8 @@ impl WriteBackendMethods for GccCodegenBackend {
 pub fn __rustc_codegen_backend() -> Box<dyn CodegenBackend> {
     #[cfg(feature = "master")]
     let info = {
-        // Check whether the target supports 128-bit integers.
+        // Check whether the target supports 128-bit integers, and sized floating point types (like
+        // Float16).
         let context = Context::default();
         Arc::new(Mutex::new(IntoDynSyncSend(context.get_target_info())))
     };
diff --git a/src/type_.rs b/src/type_.rs
index d0d3c21f0cf..184367e9cde 100644
--- a/src/type_.rs
+++ b/src/type_.rs
@@ -1,3 +1,8 @@
+#[cfg(feature = "master")]
+use std::convert::TryInto;
+
+#[cfg(feature = "master")]
+use gccjit::CType;
 use gccjit::{RValue, Struct, Type};
 use rustc_codegen_ssa::common::TypeKind;
 use rustc_codegen_ssa::traits::{BaseTypeMethods, DerivedTypeMethods, TypeMembershipMethods};
@@ -121,19 +126,35 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
     }
 
     fn type_f16(&self) -> Type<'gcc> {
-        unimplemented!("f16_f128")
+        #[cfg(feature = "master")]
+        if self.supports_f16_type {
+            return self.context.new_c_type(CType::Float16);
+        }
+        bug!("unsupported float width 16")
     }
 
     fn type_f32(&self) -> Type<'gcc> {
+        #[cfg(feature = "master")]
+        if self.supports_f32_type {
+            return self.context.new_c_type(CType::Float32);
+        }
         self.float_type
     }
 
     fn type_f64(&self) -> Type<'gcc> {
+        #[cfg(feature = "master")]
+        if self.supports_f64_type {
+            return self.context.new_c_type(CType::Float64);
+        }
         self.double_type
     }
 
     fn type_f128(&self) -> Type<'gcc> {
-        unimplemented!("f16_f128")
+        #[cfg(feature = "master")]
+        if self.supports_f128_type {
+            return self.context.new_c_type(CType::Float128);
+        }
+        bug!("unsupported float width 128")
     }
 
     fn type_func(&self, params: &[Type<'gcc>], return_type: Type<'gcc>) -> Type<'gcc> {
@@ -161,6 +182,41 @@ 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.get_pointee().is_some() {
+            TypeKind::Pointer
+        } else if typ.is_vector() {
+            TypeKind::Vector
+        } else if typ.dyncast_array().is_some() {
+            TypeKind::Array
+        } else if typ.is_struct().is_some() {
+            TypeKind::Struct
+        } else if typ.dyncast_function_ptr_type().is_some() {
+            TypeKind::Function
+        } 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_floating_point() {
+            match typ.get_size() {
+                2 => TypeKind::Half,
+                4 => TypeKind::Float,
+                8 => TypeKind::Double,
+                16 => TypeKind::FP128,
+                size => unreachable!("Floating-point type of size {}", size),
+            }
+        } else if typ == self.type_void() {
+            TypeKind::Void
+        } else {
+            // TODO(antoyo): support other types.
+            unimplemented!();
+        }
+    }
+
+    #[cfg(not(feature = "master"))]
     fn type_kind(&self, typ: Type<'gcc>) -> TypeKind {
         if self.is_int_type_or_bool(typ) {
             TypeKind::Integer
@@ -210,6 +266,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::<f32>();
         let f64 = self.context.new_type::<f64>();