Add f16
and f128
to rustc_type_ir::FloatTy
and rustc_abi::Primitive
Make changes necessary to support these types in the compiler.
This commit is contained in:
parent
ef324565d0
commit
e3f63d9375
@ -171,8 +171,10 @@ pub struct TargetDataLayout {
|
||||
pub i32_align: AbiAndPrefAlign,
|
||||
pub i64_align: AbiAndPrefAlign,
|
||||
pub i128_align: AbiAndPrefAlign,
|
||||
pub f16_align: AbiAndPrefAlign,
|
||||
pub f32_align: AbiAndPrefAlign,
|
||||
pub f64_align: AbiAndPrefAlign,
|
||||
pub f128_align: AbiAndPrefAlign,
|
||||
pub pointer_size: Size,
|
||||
pub pointer_align: AbiAndPrefAlign,
|
||||
pub aggregate_align: AbiAndPrefAlign,
|
||||
@ -200,8 +202,10 @@ fn default() -> TargetDataLayout {
|
||||
i32_align: AbiAndPrefAlign::new(align(32)),
|
||||
i64_align: AbiAndPrefAlign { abi: align(32), pref: align(64) },
|
||||
i128_align: AbiAndPrefAlign { abi: align(32), pref: align(64) },
|
||||
f16_align: AbiAndPrefAlign::new(align(16)),
|
||||
f32_align: AbiAndPrefAlign::new(align(32)),
|
||||
f64_align: AbiAndPrefAlign::new(align(64)),
|
||||
f128_align: AbiAndPrefAlign::new(align(128)),
|
||||
pointer_size: Size::from_bits(64),
|
||||
pointer_align: AbiAndPrefAlign::new(align(64)),
|
||||
aggregate_align: AbiAndPrefAlign { abi: align(0), pref: align(64) },
|
||||
@ -281,8 +285,10 @@ pub fn parse_from_llvm_datalayout_string<'a>(
|
||||
dl.instruction_address_space = parse_address_space(&p[1..], "P")?
|
||||
}
|
||||
["a", ref a @ ..] => dl.aggregate_align = parse_align(a, "a")?,
|
||||
["f16", ref a @ ..] => dl.f16_align = parse_align(a, "f16")?,
|
||||
["f32", ref a @ ..] => dl.f32_align = parse_align(a, "f32")?,
|
||||
["f64", ref a @ ..] => dl.f64_align = parse_align(a, "f64")?,
|
||||
["f128", ref a @ ..] => dl.f128_align = parse_align(a, "f128")?,
|
||||
// FIXME(erikdesjardins): we should be parsing nonzero address spaces
|
||||
// this will require replacing TargetDataLayout::{pointer_size,pointer_align}
|
||||
// with e.g. `fn pointer_size_in(AddressSpace)`
|
||||
@ -919,8 +925,10 @@ pub enum Primitive {
|
||||
/// a negative integer passed by zero-extension will appear positive in
|
||||
/// the callee, and most operations on it will produce the wrong values.
|
||||
Int(Integer, bool),
|
||||
F16,
|
||||
F32,
|
||||
F64,
|
||||
F128,
|
||||
Pointer(AddressSpace),
|
||||
}
|
||||
|
||||
@ -931,8 +939,10 @@ pub fn size<C: HasDataLayout>(self, cx: &C) -> Size {
|
||||
|
||||
match self {
|
||||
Int(i, _) => i.size(),
|
||||
F16 => Size::from_bits(16),
|
||||
F32 => Size::from_bits(32),
|
||||
F64 => Size::from_bits(64),
|
||||
F128 => Size::from_bits(128),
|
||||
// FIXME(erikdesjardins): ignoring address space is technically wrong, pointers in
|
||||
// different address spaces can have different sizes
|
||||
// (but TargetDataLayout doesn't currently parse that part of the DL string)
|
||||
@ -946,8 +956,10 @@ pub fn align<C: HasDataLayout>(self, cx: &C) -> AbiAndPrefAlign {
|
||||
|
||||
match self {
|
||||
Int(i, _) => i.align(dl),
|
||||
F16 => dl.f16_align,
|
||||
F32 => dl.f32_align,
|
||||
F64 => dl.f64_align,
|
||||
F128 => dl.f128_align,
|
||||
// FIXME(erikdesjardins): ignoring address space is technically wrong, pointers in
|
||||
// different address spaces can have different alignments
|
||||
// (but TargetDataLayout doesn't currently parse that part of the DL string)
|
||||
|
@ -33,8 +33,10 @@ pub(crate) fn scalar_to_clif_type(tcx: TyCtxt<'_>, scalar: Scalar) -> Type {
|
||||
Integer::I64 => types::I64,
|
||||
Integer::I128 => types::I128,
|
||||
},
|
||||
Primitive::F16 => unimplemented!("f16_f128"),
|
||||
Primitive::F32 => types::F32,
|
||||
Primitive::F64 => types::F64,
|
||||
Primitive::F128 => unimplemented!("f16_f128"),
|
||||
// FIXME(erikdesjardins): handle non-default addrspace ptr sizes
|
||||
Primitive::Pointer(_) => pointer_ty(tcx),
|
||||
}
|
||||
@ -61,8 +63,10 @@ fn clif_type_from_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<types::Typ
|
||||
},
|
||||
ty::Char => types::I32,
|
||||
ty::Float(size) => match size {
|
||||
FloatTy::F16 => unimplemented!("f16_f128"),
|
||||
FloatTy::F32 => types::F32,
|
||||
FloatTy::F64 => types::F64,
|
||||
FloatTy::F128 => unimplemented!("f16_f128"),
|
||||
},
|
||||
ty::FnPtr(_) => pointer_ty(tcx),
|
||||
ty::RawPtr(TypeAndMut { ty: pointee_ty, mutbl: _ }) | ty::Ref(_, pointee_ty, _) => {
|
||||
|
@ -83,8 +83,10 @@ pub fn type_vector(&self, ty: Type<'gcc>, len: u64) -> Type<'gcc> {
|
||||
|
||||
pub fn type_float_from_ty(&self, t: ty::FloatTy) -> Type<'gcc> {
|
||||
match t {
|
||||
ty::FloatTy::F16 => self.type_f16(),
|
||||
ty::FloatTy::F32 => self.type_f32(),
|
||||
ty::FloatTy::F64 => self.type_f64(),
|
||||
ty::FloatTy::F128 => self.type_f128(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -118,6 +120,10 @@ fn type_isize(&self) -> Type<'gcc> {
|
||||
self.isize_type
|
||||
}
|
||||
|
||||
fn type_f16(&self) -> Type<'gcc> {
|
||||
unimplemented!("f16_f128")
|
||||
}
|
||||
|
||||
fn type_f32(&self) -> Type<'gcc> {
|
||||
self.float_type
|
||||
}
|
||||
@ -125,6 +131,10 @@ fn type_f32(&self) -> Type<'gcc> {
|
||||
fn type_f64(&self) -> Type<'gcc> {
|
||||
self.double_type
|
||||
}
|
||||
|
||||
fn type_f128(&self) -> Type<'gcc> {
|
||||
unimplemented!("f16_f128")
|
||||
}
|
||||
|
||||
fn type_func(&self, params: &[Type<'gcc>], return_type: Type<'gcc>) -> Type<'gcc> {
|
||||
self.context.new_function_pointer_type(None, return_type, params, false)
|
||||
|
@ -6,7 +6,7 @@
|
||||
use rustc_middle::ty::{self, Ty, TypeVisitableExt};
|
||||
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
|
||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||
use rustc_target::abi::{self, Abi, Align, F32, F64, FieldsShape, Int, Integer, Pointer, PointeeInfo, Size, TyAbiInterface, Variants};
|
||||
use rustc_target::abi::{self, Abi, Align, F16, F128, F32, F64, FieldsShape, Int, Integer, Pointer, PointeeInfo, Size, TyAbiInterface, Variants};
|
||||
use rustc_target::abi::call::{CastTarget, FnAbi, Reg};
|
||||
|
||||
use crate::abi::{FnAbiGcc, FnAbiGccExt, GccType};
|
||||
@ -257,8 +257,10 @@ fn scalar_gcc_type_at<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>, scalar: &abi::Sca
|
||||
match scalar.primitive() {
|
||||
Int(i, true) => cx.type_from_integer(i),
|
||||
Int(i, false) => cx.type_from_unsigned_integer(i),
|
||||
F16 => cx.type_f16(),
|
||||
F32 => cx.type_f32(),
|
||||
F64 => cx.type_f64(),
|
||||
F128 => cx.type_f128(),
|
||||
Pointer(address_space) => {
|
||||
// If we know the alignment, pick something better than i8.
|
||||
let pointee =
|
||||
|
@ -568,7 +568,7 @@ fn scalar_load_metadata<'a, 'll, 'tcx>(
|
||||
}
|
||||
}
|
||||
}
|
||||
abi::F32 | abi::F64 => {}
|
||||
abi::F16 | abi::F32 | abi::F64 | abi::F128 => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -695,9 +695,13 @@ fn msvc_basic_name(self) -> &'static str {
|
||||
|
||||
impl MsvcBasicName for ty::FloatTy {
|
||||
fn msvc_basic_name(self) -> &'static str {
|
||||
// FIXME: f16 and f128 have no MSVE representation. We could improve the debuginfo.
|
||||
// See: <https://github.com/rust-lang/rust/pull/114607/files#r1454683264>
|
||||
match self {
|
||||
ty::FloatTy::F16 => "half",
|
||||
ty::FloatTy::F32 => "float",
|
||||
ty::FloatTy::F64 => "double",
|
||||
ty::FloatTy::F128 => "fp128",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -122,8 +122,10 @@ fn tag_base_type<'ll, 'tcx>(
|
||||
// Niche tags are always normalized to unsized integers of the correct size.
|
||||
match tag.primitive() {
|
||||
Primitive::Int(t, _) => t,
|
||||
Primitive::F16 => Integer::I16,
|
||||
Primitive::F32 => Integer::I32,
|
||||
Primitive::F64 => Integer::I64,
|
||||
Primitive::F128 => Integer::I128,
|
||||
// FIXME(erikdesjardins): handle non-default addrspace ptr sizes
|
||||
Primitive::Pointer(_) => {
|
||||
// If the niche is the NULL value of a reference, then `discr_enum_ty` will be
|
||||
|
@ -163,11 +163,15 @@ fn codegen_intrinsic_call(
|
||||
emit_va_arg(self, args[0], ret_ty)
|
||||
}
|
||||
}
|
||||
Primitive::F16 => bug!("the va_arg intrinsic does not work with `f16`"),
|
||||
Primitive::F64 | Primitive::Pointer(_) => {
|
||||
emit_va_arg(self, args[0], ret_ty)
|
||||
}
|
||||
// `va_arg` should never be used with the return type f32.
|
||||
Primitive::F32 => bug!("the va_arg intrinsic does not work with `f32`"),
|
||||
Primitive::F128 => {
|
||||
bug!("the va_arg intrinsic does not work with `f128`")
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => bug!("the va_arg intrinsic does not work with non-scalar types"),
|
||||
|
@ -858,8 +858,10 @@ pub struct AllocKindFlags : u64 {
|
||||
pub fn LLVMGetIntTypeWidth(IntegerTy: &Type) -> c_uint;
|
||||
|
||||
// Operations on real types
|
||||
pub fn LLVMHalfTypeInContext(C: &Context) -> &Type;
|
||||
pub fn LLVMFloatTypeInContext(C: &Context) -> &Type;
|
||||
pub fn LLVMDoubleTypeInContext(C: &Context) -> &Type;
|
||||
pub fn LLVMFP128TypeInContext(C: &Context) -> &Type;
|
||||
|
||||
// Operations on function types
|
||||
pub fn LLVMFunctionType<'a>(
|
||||
|
@ -107,8 +107,10 @@ pub(crate) fn type_uint_from_ty(&self, t: ty::UintTy) -> &'ll Type {
|
||||
|
||||
pub(crate) fn type_float_from_ty(&self, t: ty::FloatTy) -> &'ll Type {
|
||||
match t {
|
||||
ty::FloatTy::F16 => self.type_f16(),
|
||||
ty::FloatTy::F32 => self.type_f32(),
|
||||
ty::FloatTy::F64 => self.type_f64(),
|
||||
ty::FloatTy::F128 => self.type_f128(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -156,6 +158,10 @@ fn type_isize(&self) -> &'ll Type {
|
||||
self.isize_ty
|
||||
}
|
||||
|
||||
fn type_f16(&self) -> &'ll Type {
|
||||
unsafe { llvm::LLVMHalfTypeInContext(self.llcx) }
|
||||
}
|
||||
|
||||
fn type_f32(&self) -> &'ll Type {
|
||||
unsafe { llvm::LLVMFloatTypeInContext(self.llcx) }
|
||||
}
|
||||
@ -164,6 +170,10 @@ fn type_f64(&self) -> &'ll Type {
|
||||
unsafe { llvm::LLVMDoubleTypeInContext(self.llcx) }
|
||||
}
|
||||
|
||||
fn type_f128(&self) -> &'ll Type {
|
||||
unsafe { llvm::LLVMFP128TypeInContext(self.llcx) }
|
||||
}
|
||||
|
||||
fn type_func(&self, args: &[&'ll Type], ret: &'ll Type) -> &'ll Type {
|
||||
unsafe { llvm::LLVMFunctionType(ret, args.as_ptr(), args.len() as c_uint, False) }
|
||||
}
|
||||
@ -195,7 +205,7 @@ fn element_type(&self, ty: &'ll Type) -> &'ll Type {
|
||||
match self.type_kind(ty) {
|
||||
TypeKind::Array | TypeKind::Vector => unsafe { llvm::LLVMGetElementType(ty) },
|
||||
TypeKind::Pointer => bug!("element_type is not supported for opaque pointers"),
|
||||
other => bug!("element_type called on unsupported type {:?}", other),
|
||||
other => bug!("element_type called on unsupported type {other:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
@ -205,11 +215,12 @@ fn vector_length(&self, ty: &'ll Type) -> usize {
|
||||
|
||||
fn float_width(&self, ty: &'ll Type) -> usize {
|
||||
match self.type_kind(ty) {
|
||||
TypeKind::Half => 16,
|
||||
TypeKind::Float => 32,
|
||||
TypeKind::Double => 64,
|
||||
TypeKind::X86_FP80 => 80,
|
||||
TypeKind::FP128 | TypeKind::PPC_FP128 => 128,
|
||||
_ => bug!("llvm_float_width called on a non-float type"),
|
||||
other => bug!("llvm_float_width called on a non-float type {other:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
use rustc_middle::ty::{self, Ty, TypeVisitableExt};
|
||||
use rustc_target::abi::HasDataLayout;
|
||||
use rustc_target::abi::{Abi, Align, FieldsShape};
|
||||
use rustc_target::abi::{Int, Pointer, F32, F64};
|
||||
use rustc_target::abi::{Int, Pointer, F128, F16, F32, F64};
|
||||
use rustc_target::abi::{Scalar, Size, Variants};
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
|
||||
@ -291,8 +291,10 @@ fn immediate_llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type {
|
||||
fn scalar_llvm_type_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>, scalar: Scalar) -> &'a Type {
|
||||
match scalar.primitive() {
|
||||
Int(i, _) => cx.type_from_integer(i),
|
||||
F16 => cx.type_f16(),
|
||||
F32 => cx.type_f32(),
|
||||
F64 => cx.type_f64(),
|
||||
F128 => cx.type_f128(),
|
||||
Pointer(address_space) => cx.type_ptr_ext(address_space),
|
||||
}
|
||||
}
|
||||
|
@ -303,15 +303,17 @@ fn transmute_immediate(
|
||||
self.assume_scalar_range(bx, imm, from_scalar, from_backend_ty);
|
||||
|
||||
imm = match (from_scalar.primitive(), to_scalar.primitive()) {
|
||||
(Int(..) | F32 | F64, Int(..) | F32 | F64) => bx.bitcast(imm, to_backend_ty),
|
||||
(Int(..) | F16 | F32 | F64 | F128, Int(..) | F16 | F32 | F64 | F128) => {
|
||||
bx.bitcast(imm, to_backend_ty)
|
||||
}
|
||||
(Pointer(..), Pointer(..)) => bx.pointercast(imm, to_backend_ty),
|
||||
(Int(..), Pointer(..)) => bx.inttoptr(imm, to_backend_ty),
|
||||
(Pointer(..), Int(..)) => bx.ptrtoint(imm, to_backend_ty),
|
||||
(F32 | F64, Pointer(..)) => {
|
||||
(F16 | F32 | F64 | F128, Pointer(..)) => {
|
||||
let int_imm = bx.bitcast(imm, bx.cx().type_isize());
|
||||
bx.inttoptr(int_imm, to_backend_ty)
|
||||
}
|
||||
(Pointer(..), F32 | F64) => {
|
||||
(Pointer(..), F16 | F32 | F64 | F128) => {
|
||||
let int_imm = bx.ptrtoint(imm, bx.cx().type_isize());
|
||||
bx.bitcast(int_imm, to_backend_ty)
|
||||
}
|
||||
|
@ -19,8 +19,10 @@ pub trait BaseTypeMethods<'tcx>: Backend<'tcx> {
|
||||
fn type_i128(&self) -> Self::Type;
|
||||
fn type_isize(&self) -> Self::Type;
|
||||
|
||||
fn type_f16(&self) -> Self::Type;
|
||||
fn type_f32(&self) -> Self::Type;
|
||||
fn type_f64(&self) -> Self::Type;
|
||||
fn type_f128(&self) -> Self::Type;
|
||||
|
||||
fn type_array(&self, ty: Self::Type, len: u64) -> Self::Type;
|
||||
fn type_func(&self, args: &[Self::Type], ret: Self::Type) -> Self::Type;
|
||||
|
@ -389,12 +389,14 @@ pub fn overflowing_binary_op(
|
||||
let left = left.to_scalar();
|
||||
let right = right.to_scalar();
|
||||
Ok(match fty {
|
||||
FloatTy::F16 => unimplemented!("f16_f128"),
|
||||
FloatTy::F32 => {
|
||||
self.binary_float_op(bin_op, layout, left.to_f32()?, right.to_f32()?)
|
||||
}
|
||||
FloatTy::F64 => {
|
||||
self.binary_float_op(bin_op, layout, left.to_f64()?, right.to_f64()?)
|
||||
}
|
||||
FloatTy::F128 => unimplemented!("f16_f128"),
|
||||
})
|
||||
}
|
||||
_ if left.layout.ty.is_integral() => {
|
||||
|
@ -561,8 +561,10 @@ fn lint_literal<'tcx>(
|
||||
ty::Float(t) => {
|
||||
let is_infinite = match lit.node {
|
||||
ast::LitKind::Float(v, _) => match t {
|
||||
ty::FloatTy::F16 => unimplemented!("f16_f128"),
|
||||
ty::FloatTy::F32 => v.as_str().parse().map(f32::is_infinite),
|
||||
ty::FloatTy::F64 => v.as_str().parse().map(f64::is_infinite),
|
||||
ty::FloatTy::F128 => unimplemented!("f16_f128"),
|
||||
},
|
||||
_ => bug!(),
|
||||
};
|
||||
|
@ -337,8 +337,10 @@ pub struct CommonTypes<'tcx> {
|
||||
pub u32: Ty<'tcx>,
|
||||
pub u64: Ty<'tcx>,
|
||||
pub u128: Ty<'tcx>,
|
||||
pub f16: Ty<'tcx>,
|
||||
pub f32: Ty<'tcx>,
|
||||
pub f64: Ty<'tcx>,
|
||||
pub f128: Ty<'tcx>,
|
||||
pub str_: Ty<'tcx>,
|
||||
pub never: Ty<'tcx>,
|
||||
pub self_param: Ty<'tcx>,
|
||||
@ -418,8 +420,10 @@ fn new(
|
||||
u32: mk(Uint(ty::UintTy::U32)),
|
||||
u64: mk(Uint(ty::UintTy::U64)),
|
||||
u128: mk(Uint(ty::UintTy::U128)),
|
||||
f16: mk(Float(ty::FloatTy::F16)),
|
||||
f32: mk(Float(ty::FloatTy::F32)),
|
||||
f64: mk(Float(ty::FloatTy::F64)),
|
||||
f128: mk(Float(ty::FloatTy::F128)),
|
||||
str_: mk(Str),
|
||||
self_param: mk(ty::Param(ty::ParamTy { index: 0, name: kw::SelfUpper })),
|
||||
|
||||
|
@ -117,8 +117,10 @@ impl Primitive {
|
||||
fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
|
||||
match *self {
|
||||
Int(i, signed) => i.to_ty(tcx, signed),
|
||||
F16 => tcx.types.f16,
|
||||
F32 => tcx.types.f32,
|
||||
F64 => tcx.types.f64,
|
||||
F128 => tcx.types.f128,
|
||||
// FIXME(erikdesjardins): handle non-default addrspace ptr sizes
|
||||
Pointer(_) => Ty::new_mut_ptr(tcx, Ty::new_unit(tcx)),
|
||||
}
|
||||
@ -135,7 +137,7 @@ fn to_int_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
|
||||
let signed = false;
|
||||
tcx.data_layout().ptr_sized_integer().to_ty(tcx, signed)
|
||||
}
|
||||
F32 | F64 => bug!("floats do not have an int type"),
|
||||
F16 | F32 | F64 | F128 => bug!("floats do not have an int type"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1580,8 +1580,10 @@ pub fn new_uint(tcx: TyCtxt<'tcx>, ui: ty::UintTy) -> Ty<'tcx> {
|
||||
pub fn new_float(tcx: TyCtxt<'tcx>, f: ty::FloatTy) -> Ty<'tcx> {
|
||||
use ty::FloatTy::*;
|
||||
match f {
|
||||
F16 => tcx.types.f16,
|
||||
F32 => tcx.types.f32,
|
||||
F64 => tcx.types.f64,
|
||||
F128 => tcx.types.f128,
|
||||
}
|
||||
}
|
||||
|
||||
@ -2539,8 +2541,10 @@ pub fn primitive_symbol(self) -> Option<Symbol> {
|
||||
ty::Bool => Some(sym::bool),
|
||||
ty::Char => Some(sym::char),
|
||||
ty::Float(f) => match f {
|
||||
ty::FloatTy::F16 => Some(sym::f16),
|
||||
ty::FloatTy::F32 => Some(sym::f32),
|
||||
ty::FloatTy::F64 => Some(sym::f64),
|
||||
ty::FloatTy::F128 => Some(sym::f128),
|
||||
},
|
||||
ty::Int(f) => match f {
|
||||
ty::IntTy::Isize => Some(sym::isize),
|
||||
|
@ -1053,6 +1053,7 @@ pub(crate) fn parse_float_into_scalar(
|
||||
) -> Option<Scalar> {
|
||||
let num = num.as_str();
|
||||
match float_ty {
|
||||
ty::FloatTy::F16 => unimplemented!("f16_f128"),
|
||||
ty::FloatTy::F32 => {
|
||||
let Ok(rust_f) = num.parse::<f32>() else { return None };
|
||||
let mut f = num
|
||||
@ -1099,6 +1100,7 @@ pub(crate) fn parse_float_into_scalar(
|
||||
|
||||
Some(Scalar::from_f64(f))
|
||||
}
|
||||
ty::FloatTy::F128 => unimplemented!("f16_f128"),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -442,8 +442,10 @@ fn recur(
|
||||
ty::Float(flt) => {
|
||||
let v = cv.unwrap_leaf();
|
||||
let is_nan = match flt {
|
||||
ty::FloatTy::F16 => unimplemented!("f16_f128"),
|
||||
ty::FloatTy::F32 => v.try_to_f32().unwrap().is_nan(),
|
||||
ty::FloatTy::F64 => v.try_to_f64().unwrap().is_nan(),
|
||||
ty::FloatTy::F128 => unimplemented!("f16_f128"),
|
||||
};
|
||||
if is_nan {
|
||||
// NaNs are not ever equal to anything so they make no sense as patterns.
|
||||
|
@ -625,6 +625,7 @@ pub fn lower_pat(&self, pat: &'p Pat<'tcx>) -> DeconstructedPat<'p, 'tcx> {
|
||||
let lo = lo.as_finite().map(|c| c.eval_bits(cx.tcx, cx.param_env));
|
||||
let hi = hi.as_finite().map(|c| c.eval_bits(cx.tcx, cx.param_env));
|
||||
match fty {
|
||||
ty::FloatTy::F16 => unimplemented!("f16_f128"),
|
||||
ty::FloatTy::F32 => {
|
||||
use rustc_apfloat::ieee::Single;
|
||||
let lo = lo.map(Single::from_bits).unwrap_or(-Single::INFINITY);
|
||||
@ -637,6 +638,7 @@ pub fn lower_pat(&self, pat: &'p Pat<'tcx>) -> DeconstructedPat<'p, 'tcx> {
|
||||
let hi = hi.map(Double::from_bits).unwrap_or(Double::INFINITY);
|
||||
F64Range(lo, hi, end)
|
||||
}
|
||||
ty::FloatTy::F128 => unimplemented!("f16_f128"),
|
||||
}
|
||||
}
|
||||
_ => bug!("invalid type for range pattern: {}", ty.inner()),
|
||||
|
@ -297,8 +297,10 @@ impl<'tcx> Stable<'tcx> for ty::FloatTy {
|
||||
|
||||
fn stable(&self, _: &mut Tables<'_>) -> Self::T {
|
||||
match self {
|
||||
ty::FloatTy::F16 => unimplemented!("f16_f128"),
|
||||
ty::FloatTy::F32 => FloatTy::F32,
|
||||
ty::FloatTy::F64 => FloatTy::F64,
|
||||
ty::FloatTy::F128 => unimplemented!("f16_f128"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -758,6 +758,8 @@
|
||||
external,
|
||||
external_doc,
|
||||
f,
|
||||
f128,
|
||||
f16,
|
||||
f16c_target_feature,
|
||||
f32,
|
||||
f32_legacy_const_digits,
|
||||
|
@ -470,8 +470,10 @@ fn encode_ty<'tcx>(
|
||||
// (See https://rust-lang.github.io/unsafe-code-guidelines/layout/scalars.html#fixed-width-floating-point-types.)
|
||||
ty::Float(float_ty) => {
|
||||
typeid.push(match float_ty {
|
||||
FloatTy::F16 => unimplemented!("f16_f128"),
|
||||
FloatTy::F32 => 'f',
|
||||
FloatTy::F64 => 'd',
|
||||
FloatTy::F128 => unimplemented!("f16_f128"),
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -59,7 +59,7 @@ fn should_use_fp_conv_helper<'a, Ty, C>(
|
||||
_ => return Err(CannotUseFpConv),
|
||||
}
|
||||
}
|
||||
abi::F32 | abi::F64 => {
|
||||
abi::F16 | abi::F32 | abi::F64 | abi::F128 => {
|
||||
if arg_layout.size.bits() > flen {
|
||||
return Err(CannotUseFpConv);
|
||||
}
|
||||
|
@ -412,7 +412,7 @@ pub fn homogeneous_aggregate<C>(&self, cx: &C) -> Result<HomogeneousAggregate, H
|
||||
Abi::Scalar(scalar) => {
|
||||
let kind = match scalar.primitive() {
|
||||
abi::Int(..) | abi::Pointer(_) => RegKind::Integer,
|
||||
abi::F32 | abi::F64 => RegKind::Float,
|
||||
abi::F16 | abi::F32 | abi::F64 | abi::F128 => RegKind::Float,
|
||||
};
|
||||
Ok(HomogeneousAggregate::Homogeneous(Reg { kind, size: self.size }))
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ fn should_use_fp_conv_helper<'a, Ty, C>(
|
||||
_ => return Err(CannotUseFpConv),
|
||||
}
|
||||
}
|
||||
abi::F32 | abi::F64 => {
|
||||
abi::F16 | abi::F32 | abi::F64 | abi::F128 => {
|
||||
if arg_layout.size.bits() > flen {
|
||||
return Err(CannotUseFpConv);
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ fn classify<'a, Ty, C>(
|
||||
|
||||
Abi::Scalar(scalar) => match scalar.primitive() {
|
||||
abi::Int(..) | abi::Pointer(_) => Class::Int,
|
||||
abi::F32 | abi::F64 => Class::Sse,
|
||||
abi::F16 | abi::F32 | abi::F64 | abi::F128 => Class::Sse,
|
||||
},
|
||||
|
||||
Abi::Vector { .. } => Class::Sse,
|
||||
|
@ -394,10 +394,12 @@ fn assemble_non_blanket_impl_candidates<G: GoalKind<'tcx>>(
|
||||
|
||||
ty::Infer(ty::FloatVar(_)) => {
|
||||
// This causes a compiler error if any new float kinds are added.
|
||||
let (ty::FloatTy::F32 | ty::FloatTy::F64);
|
||||
let (ty::FloatTy::F16 | ty::FloatTy::F32 | ty::FloatTy::F64 | ty::FloatTy::F128);
|
||||
let possible_floats = [
|
||||
SimplifiedType::Float(ty::FloatTy::F16),
|
||||
SimplifiedType::Float(ty::FloatTy::F32),
|
||||
SimplifiedType::Float(ty::FloatTy::F64),
|
||||
SimplifiedType::Float(ty::FloatTy::F128),
|
||||
];
|
||||
|
||||
for simp in possible_floats {
|
||||
|
@ -141,8 +141,10 @@ fn layout_of_uncached<'tcx>(
|
||||
ty::Int(ity) => scalar(Int(Integer::from_int_ty(dl, ity), true)),
|
||||
ty::Uint(ity) => scalar(Int(Integer::from_uint_ty(dl, ity), false)),
|
||||
ty::Float(fty) => scalar(match fty {
|
||||
ty::FloatTy::F16 => F16,
|
||||
ty::FloatTy::F32 => F32,
|
||||
ty::FloatTy::F64 => F64,
|
||||
ty::FloatTy::F128 => F128,
|
||||
}),
|
||||
ty::FnPtr(_) => {
|
||||
let mut ptr = scalar_unit(Pointer(dl.instruction_address_space));
|
||||
|
@ -610,22 +610,28 @@ pub fn to_signed(self) -> IntTy {
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_NoContext))]
|
||||
pub enum FloatTy {
|
||||
F16,
|
||||
F32,
|
||||
F64,
|
||||
F128,
|
||||
}
|
||||
|
||||
impl FloatTy {
|
||||
pub fn name_str(self) -> &'static str {
|
||||
match self {
|
||||
FloatTy::F16 => "f16",
|
||||
FloatTy::F32 => "f32",
|
||||
FloatTy::F64 => "f64",
|
||||
FloatTy::F128 => "f128",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bit_width(self) -> u64 {
|
||||
match self {
|
||||
FloatTy::F16 => 16,
|
||||
FloatTy::F32 => 32,
|
||||
FloatTy::F64 => 64,
|
||||
FloatTy::F128 => 128,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user