Skip to content
Draft
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
5 changes: 4 additions & 1 deletion compiler/rustc_abi/src/callconv.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#[cfg(feature = "nightly")]
use crate::{BackendRepr, FieldsShape, Primitive, Size, TyAbiInterface, TyAndLayout, Variants};
use crate::{
BackendRepr, FieldsShape, Float, Primitive, Size, TyAbiInterface, TyAndLayout, Variants,
};

mod reg;

Expand Down Expand Up @@ -71,6 +73,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
BackendRepr::Scalar(scalar) => {
let kind = match scalar.primitive() {
Primitive::Int(..) | Primitive::Pointer(_) => RegKind::Integer,
Primitive::Float(Float::PpcF128) => RegKind::DoubleDouble,
Primitive::Float(_) => RegKind::Float,
};
Ok(HomogeneousAggregate::Homogeneous(Reg { kind, size: self.size }))
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_abi/src/callconv/reg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ use crate::{Align, HasDataLayout, Integer, Primitive, Size};
pub enum RegKind {
Integer,
Float,
/// The IBM extended-precision format: a pair of `f64`s, each passed in its own register.
/// This variant is needed to distinguish IEEE f128 and IBM f128 in the backends.
///
/// Only used on PowerPC targets.
DoubleDouble,
Vector {
/// The `hint_vector_elem` is strictly for optimization purposes. E.g. it can be used by
/// a codegen backend to prevent extra bitcasts that obscure a pattern. Alternatively,
Expand Down Expand Up @@ -69,6 +74,7 @@ impl Reg {
128 => dl.f128_align,
_ => panic!("unsupported float: {self:?}"),
},
RegKind::DoubleDouble => dl.f128_align,
RegKind::Vector { .. } => dl.rust_vector_align(self.size),
}
}
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_abi/src/layout/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,10 +321,11 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
match primitive {
// Explicitly spell out all the float types so that any new ones have to be added to
// one of the match branches.
Primitive::Int(..)
| Primitive::Float(Float::F16 | Float::F32 | Float::F64 | Float::F128) => {
Primitive::Int(..) => Some(primitive),
Primitive::Float(Float::F16 | Float::F32 | Float::F64 | Float::F128) => {
Some(primitive)
}
Primitive::Float(Float::PpcF128) => Some(primitive),
Primitive::Pointer(..) => None,
}
} else {
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_abi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1413,6 +1413,7 @@ pub enum Float {
F32,
F64,
F128,
PpcF128,
}

impl Float {
Expand All @@ -1424,6 +1425,7 @@ impl Float {
F32 => Size::from_bits(32),
F64 => Size::from_bits(64),
F128 => Size::from_bits(128),
PpcF128 => Size::from_bits(128),
}
}

Expand All @@ -1436,6 +1438,7 @@ impl Float {
F32 => dl.f32_align,
F64 => dl.f64_align,
F128 => dl.f128_align,
PpcF128 => dl.f128_align,
})
}

Expand All @@ -1447,6 +1450,7 @@ impl Float {
F32 => "f32",
F64 => "f64",
F128 => "f128",
PpcF128 => "ppcf128",
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_ast_ir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ pub enum FloatTy {
F32,
F64,
F128,
PpcF128,
}

impl FloatTy {
Expand All @@ -188,6 +189,7 @@ impl FloatTy {
FloatTy::F32 => "f32",
FloatTy::F64 => "f64",
FloatTy::F128 => "f128",
FloatTy::PpcF128 => "ppcf128",
}
}

Expand All @@ -198,6 +200,7 @@ impl FloatTy {
FloatTy::F32 => sym::f32,
FloatTy::F64 => sym::f64,
FloatTy::F128 => sym::f128,
FloatTy::PpcF128 => sym::ppcf128,
}
}

Expand All @@ -207,6 +210,7 @@ impl FloatTy {
FloatTy::F32 => 32,
FloatTy::F64 => 64,
FloatTy::F128 => 128,
FloatTy::PpcF128 => 128,
}
}
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_attr_ir/src/lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ language_item_table! {
VaList, sym::va_list, va_list, Target::Struct, GenericRequirement::None;

Complex, sym::complex, complex, Target::Struct, GenericRequirement::Exact(1);
PpcF128, sym::ppcf128, ppcf128_type, Target::Struct, GenericRequirement::None;

Deref, sym::deref, deref_trait, Target::Trait, GenericRequirement::Exact(0);
DerefMut, sym::deref_mut, deref_mut_trait, Target::Trait, GenericRequirement::Exact(0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ diff --git a/coretests/tests/lib.rs b/coretests/tests/lib.rs
index 1e336bf..35e6f54 100644
--- a/coretests/tests/lib.rs
+++ b/coretests/tests/lib.rs
@@ -2,4 +2,3 @@
@@ -2,7 +2,6 @@
// tidy-alphabetical-start
#![cfg_attr(any(target_arch = "powerpc", target_arch = "powerpc64"), feature(powerpc_ppcf128))]
#![cfg_attr(any(target_arch = "powerpc", target_arch = "powerpc64"), feature(stdarch_powerpc))]
#![cfg_attr(not(panic = "abort"), feature(reentrant_lock))]
-#![cfg_attr(target_has_atomic = "128", feature(integer_atomics))]
#![feature(array_ptr_get)]
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_codegen_cranelift/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ pub(crate) fn scalar_to_clif_type(tcx: TyCtxt<'_>, scalar: Scalar) -> Type {
Float::F32 => types::F32,
Float::F64 => types::F64,
Float::F128 => types::F128,
Float::PpcF128 => bug!("cranelift does not support powerpc"),
},
// FIXME(erikdesjardins): handle non-default addrspace ptr sizes
Primitive::Pointer(_) => pointer_ty(tcx),
Expand Down Expand Up @@ -68,6 +69,7 @@ fn clif_type_from_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<types::Typ
FloatTy::F32 => types::F32,
FloatTy::F64 => types::F64,
FloatTy::F128 => types::F128,
FloatTy::PpcF128 => bug!("cranelift does not support powerpc"),
},
ty::FnPtr(..) => pointer_ty(tcx),
ty::RawPtr(pointee_ty, _) | ty::Ref(_, pointee_ty, _) => {
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_gcc/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ impl GccType for Reg {
64 => cx.type_f64(),
_ => bug!("unsupported float: {:?}", self),
},
RegKind::DoubleDouble => cx.type_ppcf128(),
RegKind::Vector { hint_vector_elem: _ } => {
cx.type_vector(cx.type_i8(), self.size.bytes())
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
}
get_simple_function_f128(span, self, name)
}
(_, PpcF128) => span_bug!(span, "ppcf128 {name} is unimplemented"),
};
self.cx.context.new_call(
self.location,
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_codegen_gcc/src/type_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
ty::FloatTy::F32 => self.type_f32(),
ty::FloatTy::F64 => self.type_f64(),
ty::FloatTy::F128 => self.type_f128(),
ty::FloatTy::PpcF128 => self.type_ppcf128(),
}
}

Expand Down Expand Up @@ -180,6 +181,10 @@ impl<'gcc, 'tcx> BaseTypeCodegenMethods for CodegenCx<'gcc, 'tcx> {
bug!("unsupported float width 128")
}

fn type_ppcf128(&self) -> Type<'gcc> {
bug!("unsupported ppcf128 type")
}

fn type_func(&self, params: &[Type<'gcc>], return_type: Type<'gcc>) -> Type<'gcc> {
self.context.new_function_pointer_type(None, return_type, params, false)
}
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_codegen_llvm/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ impl LlvmType for Reg {
128 => cx.type_f128(),
_ => bug!("unsupported float: {:?}", self),
},
RegKind::DoubleDouble => cx.type_ppcf128(),
RegKind::Vector { hint_vector_elem } => {
// NOTE: it is valid to ignore the element type hint (and always pick i8).
// But providing a more accurate type means fewer casts in LLVM IR,
Expand All @@ -161,6 +162,7 @@ impl LlvmType for Reg {
Float::F32 => cx.type_f32(),
Float::F64 => cx.type_f64(),
Float::F128 => cx.type_f128(),
Float::PpcF128 => cx.type_ppcf128(),
},
Primitive::Pointer(_) => cx.type_ptr(),
};
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -703,6 +703,7 @@ impl MsvcBasicName for ty::FloatTy {
ty::FloatTy::F32 => "float",
ty::FloatTy::F64 => "double",
ty::FloatTy::F128 => "fp128",
ty::FloatTy::PpcF128 => bug!("MSVC does not support powerpc"),
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_codegen_llvm/src/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,10 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
// FIXME(f128) figure out whether we should support this.
bug!("the va_arg intrinsic does not support `f128`")
}
Primitive::Float(Float::PpcF128) => {
// FIXME(ppcf128) we should support this.
bug!("the va_arg intrinsic does not currently support `ppcf128`")
}
}

emit_va_arg(self, args[0], result_layout.ty)
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_llvm/src/llvm/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -939,6 +939,7 @@ unsafe extern "C" {
pub(crate) fn LLVMFloatTypeInContext(C: &Context) -> &Type;
pub(crate) fn LLVMDoubleTypeInContext(C: &Context) -> &Type;
pub(crate) fn LLVMFP128TypeInContext(C: &Context) -> &Type;
pub(crate) fn LLVMPPCFP128TypeInContext(C: &Context) -> &Type;

// Operations on non-IEEE real types
pub(crate) fn LLVMBFloatTypeInContext(C: &Context) -> &Type;
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_codegen_llvm/src/type_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
ty::FloatTy::F32 => self.type_f32(),
ty::FloatTy::F64 => self.type_f64(),
ty::FloatTy::F128 => self.type_f128(),
ty::FloatTy::PpcF128 => self.type_ppcf128(),
}
}

Expand Down Expand Up @@ -226,6 +227,10 @@ impl<'ll, CX: Borrow<SCx<'ll>>> BaseTypeCodegenMethods for GenericCx<'ll, CX> {
unsafe { llvm::LLVMFP128TypeInContext(self.llcx()) }
}

fn type_ppcf128(&self) -> &'ll Type {
unsafe { llvm::LLVMPPCFP128TypeInContext(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) }
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_llvm/src/va_arg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ fn get_param_type_alignment<'ll, 'tcx>(
Float::F16 | Float::F32 => unreachable!(),
Float::F64 => { /* fall through */ }
Float::F128 => return Align::from_bytes(16).unwrap(),
Float::PpcF128 => { /* fall through */ }
},
Primitive::Pointer(_) => { /* fall through */ }
},
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_codegen_ssa/src/mir/naked_asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,7 @@ fn wasm_type<'tcx>(signature: &mut String, arg_abi: &ArgAbi<'_, Ty<'tcx>>, ptr_t
..=8 => "f64",
_ => ptr_type,
},
RegKind::DoubleDouble => bug!("not a valid wasm type"),
RegKind::Vector { .. } => "v128",
};

Expand All @@ -511,6 +512,7 @@ fn wasm_primitive(primitive: Primitive, ptr_type: &'static str) -> &'static str
Float::F16 | Float::F32 => "f32",
Float::F64 => "f64",
Float::F128 => "i64, i64",
Float::PpcF128 => bug!("not a valid wasm type"),
},
Primitive::Pointer(_) => ptr_type,
}
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_codegen_ssa/src/traits/type_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ pub trait BaseTypeCodegenMethods: BackendTypes {
fn type_f32(&self) -> Self::Type;
fn type_f64(&self) -> Self::Type;
fn type_f128(&self) -> Self::Type;
fn type_ppcf128(&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::FunctionSignature;
Expand Down Expand Up @@ -70,6 +71,7 @@ pub trait DerivedTypeCodegenMethods<'tcx>:
F32 => self.type_f32(),
F64 => self.type_f64(),
F128 => self.type_f128(),
PpcF128 => self.type_ppcf128(),
}
}

Expand Down
20 changes: 19 additions & 1 deletion compiler/rustc_const_eval/src/interpret/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ use std::assert_matches;

use rustc_abi::{FieldIdx, Integer};
use rustc_apfloat::ieee::{Double, Half, Quad, Single};
use rustc_apfloat::ppc::DoubleDouble;
use rustc_apfloat::{Float, FloatConvert};
use rustc_middle::mir::CastKind;
use rustc_middle::mir::interpret::{InterpResult, PointerArithmetic, Scalar};
use rustc_middle::ty::adjustment::PointerCoercion;
use rustc_middle::ty::layout::{IntegerExt, TyAndLayout};
use rustc_middle::ty::layout::{HasTyCtxt, IntegerExt, TyAndLayout};
use rustc_middle::ty::{self, FloatTy, Ty};
use rustc_middle::{bug, span_bug};
use rustc_target::spec::HasTargetSpec;
use tracing::trace;

use super::util::ensure_monomorphic_enough;
Expand Down Expand Up @@ -249,6 +251,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
FloatTy::F32 => self.cast_from_float(src.to_scalar().to_f32()?, cast_to.ty),
FloatTy::F64 => self.cast_from_float(src.to_scalar().to_f64()?, cast_to.ty),
FloatTy::F128 => self.cast_from_float(src.to_scalar().to_f128()?, cast_to.ty),
FloatTy::PpcF128 => {
// FIXME(ppcf128): this needs a better algorithm in rustc_apfloat.
span_bug!(self.cur_span(), "casting ppcf128 is not currently supported")
}
};
interp_ok(ImmTy::from_scalar(val, cast_to))
}
Expand Down Expand Up @@ -330,6 +336,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
src_layout: TyAndLayout<'tcx>,
cast_ty: Ty<'tcx>,
) -> InterpResult<'tcx, Scalar<M::Provenance>> {
let target_endian = self.tcx().target_spec().endian;

// Let's make sure v is sign-extended *if* it has a signed type.
let signed = src_layout.backend_repr.is_signed(); // Also asserts that abi is `Scalar`.

Expand Down Expand Up @@ -362,6 +370,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
FloatTy::F32 => Scalar::from_f32(Single::from_i128(v).value),
FloatTy::F64 => Scalar::from_f64(Double::from_i128(v).value),
FloatTy::F128 => Scalar::from_f128(Quad::from_i128(v).value),
FloatTy::PpcF128 => {
Scalar::from_ppcf128(DoubleDouble::from_i128(v).value, target_endian)
}
}
}
// unsigned int -> float
Expand All @@ -370,6 +381,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
FloatTy::F32 => Scalar::from_f32(Single::from_u128(v).value),
FloatTy::F64 => Scalar::from_f64(Double::from_u128(v).value),
FloatTy::F128 => Scalar::from_f128(Quad::from_u128(v).value),
FloatTy::PpcF128 => {
Scalar::from_ppcf128(DoubleDouble::from_u128(v).value, target_endian)
}
},

// u8 -> char
Expand Down Expand Up @@ -422,6 +436,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
FloatTy::F128 => {
Scalar::from_f128(self.adjust_nan(f.convert(&mut false).value, &[f]))
}
FloatTy::PpcF128 => {
// FIXME(ppcf128): this needs a better algorithm in rustc_apfloat.
span_bug!(self.cur_span(), "casting ppcf128 is not currently supported")
}
},
// That's it.
_ => span_bug!(self.cur_span(), "invalid float to {} cast", dest_ty),
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_const_eval/src/interpret/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
FloatTy::F32 => self.unop_float_intrinsic::<Single>(intrinsic_name, arg)?,
FloatTy::F64 => self.unop_float_intrinsic::<Double>(intrinsic_name, arg)?,
FloatTy::F128 => self.unop_float_intrinsic::<Quad>(intrinsic_name, arg)?,
FloatTy::PpcF128 => {
span_bug!(self.cur_span(), "fabs on ppcf128 is unimplemented")
}
};
self.write_scalar(out_val, dest)?;
}
Expand Down Expand Up @@ -1377,6 +1380,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
FloatTy::F32 => float_to_int_inner(self, src.to_scalar().to_f32()?, cast_to, round),
FloatTy::F64 => float_to_int_inner(self, src.to_scalar().to_f64()?, cast_to, round),
FloatTy::F128 => float_to_int_inner(self, src.to_scalar().to_f128()?, cast_to, round),
FloatTy::PpcF128 => {
let target_endian = self.tcx.sess.target.options.endian;
float_to_int_inner(self, src.to_scalar().to_ppcf128(target_endian)?, cast_to, round)
}
};

if status.intersects(
Expand Down
Loading
Loading