Merge pull request #17 from zedar/add_support_for_float16_float128
Add support for Float16, Float32, Float64 and Float128
This commit is contained in:
commit
70d36558ee
8
Cargo.lock
generated
8
Cargo.lock
generated
@ -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",
|
||||
]
|
||||
|
@ -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" }
|
||||
|
@ -1 +1 @@
|
||||
b6f163f52
|
||||
d61ce945badf4c9d8237a13ca135e3c46ad13be3
|
||||
|
21
src/base.rs
21
src/base.rs
@ -2,7 +2,7 @@
|
||||
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 @@ fn module_codegen(
|
||||
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 {
|
||||
|
@ -748,6 +748,24 @@ fn frem(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> {
|
||||
// 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());
|
||||
|
||||
|
@ -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 @@ pub fn new(
|
||||
sizet_type,
|
||||
|
||||
supports_128bit_integers,
|
||||
supports_f16_type,
|
||||
supports_f32_type,
|
||||
supports_f64_type,
|
||||
supports_f128_type,
|
||||
|
||||
float_type,
|
||||
double_type,
|
||||
|
12
src/lib.rs
12
src/lib.rs
@ -89,7 +89,6 @@
|
||||
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 @@ fn cpu_supports(&self, _feature: &str) -> bool {
|
||||
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 @@ fn cpu_supports(&self, feature: &str) -> bool {
|
||||
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 @@ fn run_link(
|
||||
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())))
|
||||
};
|
||||
|
70
src/type_.rs
70
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 @@ fn type_isize(&self) -> Type<'gcc> {
|
||||
}
|
||||
|
||||
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 @@ fn type_struct(&self, fields: &[Type<'gcc>], packed: bool) -> Type<'gcc> {
|
||||
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 @@ fn vector_length(&self, _ty: Type<'gcc>) -> usize {
|
||||
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>();
|
||||
|
Loading…
Reference in New Issue
Block a user