Auto merge of #145074 - tgross35:rollup-0tillrm, r=tgross35
Rollup of 9 pull requests Successful merges: - rust-lang/rust#144705 (compiler-builtins: plumb LSE support for aarch64 on linux/gnu when optimized-compiler-builtins not enabled) - rust-lang/rust#144857 (Port `#[allow_internal_unsafe]` to the new attribute system) - rust-lang/rust#144900 (Stabilize `unsigned_signed_diff` feature) - rust-lang/rust#144903 (Rename `begin_panic_handler` to `panic_handler`) - rust-lang/rust#144974 (compiler-builtins subtree update) - rust-lang/rust#145007 (Fix build/doc/test of error index generator) - rust-lang/rust#145018 (Derive `Hash` for rustc_public types) - rust-lang/rust#145045 (doc(library): Fix Markdown in `Iterator::by_ref`) - rust-lang/rust#145046 (Fix doc comment of File::try_lock and File::try_lock_shared) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
67d45f49e0
197 changed files with 825 additions and 716 deletions
|
|
@ -113,3 +113,11 @@ impl<S: Stage> AttributeParser<S> for MacroUseParser {
|
|||
Some(AttributeKind::MacroUse { span: self.first_span?, arguments: self.state })
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct AllowInternalUnsafeParser;
|
||||
|
||||
impl<S: Stage> NoArgsAttributeParser<S> for AllowInternalUnsafeParser {
|
||||
const PATH: &[Symbol] = &[sym::allow_internal_unsafe];
|
||||
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Ignore;
|
||||
const CREATE: fn(Span) -> AttributeKind = |span| AttributeKind::AllowInternalUnsafe(span);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,9 @@ use crate::attributes::lint_helpers::{
|
|||
AsPtrParser, AutomaticallyDerivedParser, PassByValueParser, PubTransparentParser,
|
||||
};
|
||||
use crate::attributes::loop_match::{ConstContinueParser, LoopMatchParser};
|
||||
use crate::attributes::macro_attrs::{MacroEscapeParser, MacroUseParser};
|
||||
use crate::attributes::macro_attrs::{
|
||||
AllowInternalUnsafeParser, MacroEscapeParser, MacroUseParser,
|
||||
};
|
||||
use crate::attributes::must_use::MustUseParser;
|
||||
use crate::attributes::no_implicit_prelude::NoImplicitPreludeParser;
|
||||
use crate::attributes::non_exhaustive::NonExhaustiveParser;
|
||||
|
|
@ -178,6 +180,7 @@ attribute_parsers!(
|
|||
Single<SkipDuringMethodDispatchParser>,
|
||||
Single<TransparencyParser>,
|
||||
Single<WithoutArgs<AllowIncoherentImplParser>>,
|
||||
Single<WithoutArgs<AllowInternalUnsafeParser>>,
|
||||
Single<WithoutArgs<AsPtrParser>>,
|
||||
Single<WithoutArgs<AutomaticallyDerivedParser>>,
|
||||
Single<WithoutArgs<CoherenceIsCoreParser>>,
|
||||
|
|
|
|||
|
|
@ -905,10 +905,7 @@ impl SyntaxExtension {
|
|||
find_attr!(attrs, AttributeKind::AllowInternalUnstable(i, _) => i)
|
||||
.map(|i| i.as_slice())
|
||||
.unwrap_or_default();
|
||||
// FIXME(jdonszelman): allow_internal_unsafe isn't yet new-style
|
||||
// let allow_internal_unsafe = find_attr!(attrs, AttributeKind::AllowInternalUnsafe);
|
||||
let allow_internal_unsafe =
|
||||
ast::attr::find_by_name(attrs, sym::allow_internal_unsafe).is_some();
|
||||
let allow_internal_unsafe = find_attr!(attrs, AttributeKind::AllowInternalUnsafe(_));
|
||||
|
||||
let local_inner_macros = ast::attr::find_by_name(attrs, sym::macro_export)
|
||||
.and_then(|macro_export| macro_export.meta_item_list())
|
||||
|
|
|
|||
|
|
@ -249,6 +249,9 @@ pub enum AttributeKind {
|
|||
/// Represents `#[rustc_allow_incoherent_impl]`.
|
||||
AllowIncoherentImpl(Span),
|
||||
|
||||
/// Represents `#[allow_internal_unsafe]`.
|
||||
AllowInternalUnsafe(Span),
|
||||
|
||||
/// Represents `#[allow_internal_unstable]`.
|
||||
AllowInternalUnstable(ThinVec<(Symbol, Span)>, Span),
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ impl AttributeKind {
|
|||
Align { .. } => No,
|
||||
AllowConstFnUnstable(..) => No,
|
||||
AllowIncoherentImpl(..) => No,
|
||||
AllowInternalUnsafe(..) => Yes,
|
||||
AllowInternalUnstable(..) => Yes,
|
||||
AsPtr(..) => Yes,
|
||||
AutomaticallyDerived(..) => Yes,
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
//! [`crate::late_lint_methods!`] invocation in `lib.rs`.
|
||||
|
||||
use std::fmt::Write;
|
||||
use std::slice;
|
||||
|
||||
use ast::token::TokenKind;
|
||||
use rustc_abi::BackendRepr;
|
||||
|
|
@ -21,6 +22,7 @@ use rustc_ast::tokenstream::{TokenStream, TokenTree};
|
|||
use rustc_ast::visit::{FnCtxt, FnKind};
|
||||
use rustc_ast::{self as ast, *};
|
||||
use rustc_ast_pretty::pprust::expr_to_string;
|
||||
use rustc_attr_parsing::AttributeParser;
|
||||
use rustc_errors::{Applicability, LintDiagnostic};
|
||||
use rustc_feature::GateIssue;
|
||||
use rustc_hir as hir;
|
||||
|
|
@ -249,7 +251,16 @@ impl UnsafeCode {
|
|||
|
||||
impl EarlyLintPass for UnsafeCode {
|
||||
fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &ast::Attribute) {
|
||||
if attr.has_name(sym::allow_internal_unsafe) {
|
||||
if AttributeParser::parse_limited(
|
||||
cx.builder.sess(),
|
||||
slice::from_ref(attr),
|
||||
sym::allow_internal_unsafe,
|
||||
attr.span,
|
||||
DUMMY_NODE_ID,
|
||||
Some(cx.builder.features()),
|
||||
)
|
||||
.is_some()
|
||||
{
|
||||
self.report_unsafe(cx, attr.span, BuiltinUnsafe::AllowInternalUnsafe);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ passes_allow_incoherent_impl =
|
|||
`rustc_allow_incoherent_impl` attribute should be applied to impl items
|
||||
.label = the only currently supported targets are inherent methods
|
||||
|
||||
passes_allow_internal_unstable =
|
||||
passes_macro_only_attribute =
|
||||
attribute should be applied to a macro
|
||||
.label = not a macro
|
||||
|
||||
|
|
|
|||
|
|
@ -207,6 +207,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
Attribute::Parsed(AttributeKind::ConstContinue(attr_span)) => {
|
||||
self.check_const_continue(hir_id, *attr_span, target)
|
||||
}
|
||||
Attribute::Parsed(AttributeKind::AllowInternalUnsafe(attr_span)) => {
|
||||
self.check_allow_internal_unsafe(hir_id, *attr_span, span, target, attrs)
|
||||
}
|
||||
Attribute::Parsed(AttributeKind::AllowInternalUnstable(_, first_span)) => {
|
||||
self.check_allow_internal_unstable(hir_id, *first_span, span, target, attrs)
|
||||
}
|
||||
|
|
@ -413,7 +416,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
// internal
|
||||
| sym::prelude_import
|
||||
| sym::panic_handler
|
||||
| sym::allow_internal_unsafe
|
||||
| sym::lang
|
||||
| sym::needs_allocator
|
||||
| sym::default_lib_allocator
|
||||
|
|
@ -2212,7 +2214,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
|
||||
/// Outputs an error for `#[allow_internal_unstable]` which can only be applied to macros.
|
||||
/// (Allows proc_macro functions)
|
||||
// FIXME(jdonszelmann): if possible, move to attr parsing
|
||||
fn check_allow_internal_unstable(
|
||||
&self,
|
||||
hir_id: HirId,
|
||||
|
|
@ -2220,6 +2221,42 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
span: Span,
|
||||
target: Target,
|
||||
attrs: &[Attribute],
|
||||
) {
|
||||
self.check_macro_only_attr(
|
||||
hir_id,
|
||||
attr_span,
|
||||
span,
|
||||
target,
|
||||
attrs,
|
||||
"allow_internal_unstable",
|
||||
)
|
||||
}
|
||||
|
||||
/// Outputs an error for `#[allow_internal_unsafe]` which can only be applied to macros.
|
||||
/// (Allows proc_macro functions)
|
||||
fn check_allow_internal_unsafe(
|
||||
&self,
|
||||
hir_id: HirId,
|
||||
attr_span: Span,
|
||||
span: Span,
|
||||
target: Target,
|
||||
attrs: &[Attribute],
|
||||
) {
|
||||
self.check_macro_only_attr(hir_id, attr_span, span, target, attrs, "allow_internal_unsafe")
|
||||
}
|
||||
|
||||
/// Outputs an error for attributes that can only be applied to macros, such as
|
||||
/// `#[allow_internal_unsafe]` and `#[allow_internal_unstable]`.
|
||||
/// (Allows proc_macro functions)
|
||||
// FIXME(jdonszelmann): if possible, move to attr parsing
|
||||
fn check_macro_only_attr(
|
||||
&self,
|
||||
hir_id: HirId,
|
||||
attr_span: Span,
|
||||
span: Span,
|
||||
target: Target,
|
||||
attrs: &[Attribute],
|
||||
attr_name: &str,
|
||||
) {
|
||||
match target {
|
||||
Target::Fn => {
|
||||
|
|
@ -2238,18 +2275,14 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
// erroneously allowed it and some crates used it accidentally, to be compatible
|
||||
// with crates depending on them, we can't throw an error here.
|
||||
Target::Field | Target::Arm => {
|
||||
self.inline_attr_str_error_without_macro_def(
|
||||
hir_id,
|
||||
attr_span,
|
||||
"allow_internal_unstable",
|
||||
);
|
||||
self.inline_attr_str_error_without_macro_def(hir_id, attr_span, attr_name);
|
||||
return;
|
||||
}
|
||||
// otherwise continue out of the match
|
||||
_ => {}
|
||||
}
|
||||
|
||||
self.tcx.dcx().emit_err(errors::AllowInternalUnstable { attr_span, span });
|
||||
self.tcx.dcx().emit_err(errors::MacroOnlyAttribute { attr_span, span });
|
||||
}
|
||||
|
||||
/// Checks if the items on the `#[debugger_visualizer]` attribute are valid.
|
||||
|
|
|
|||
|
|
@ -643,8 +643,8 @@ pub(crate) struct UsedStatic {
|
|||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(passes_allow_internal_unstable)]
|
||||
pub(crate) struct AllowInternalUnstable {
|
||||
#[diag(passes_macro_only_attribute)]
|
||||
pub(crate) struct MacroOnlyAttribute {
|
||||
#[primary_span]
|
||||
pub attr_span: Span,
|
||||
#[label]
|
||||
|
|
|
|||
|
|
@ -349,7 +349,7 @@ impl AssertMessage {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Serialize)]
|
||||
pub enum BinOp {
|
||||
Add,
|
||||
AddUnchecked,
|
||||
|
|
@ -384,7 +384,7 @@ impl BinOp {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Serialize)]
|
||||
pub enum UnOp {
|
||||
Not,
|
||||
Neg,
|
||||
|
|
@ -490,7 +490,7 @@ pub enum StatementKind {
|
|||
Nop,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
|
||||
pub enum Rvalue {
|
||||
/// Creates a pointer with the indicated mutability to the place.
|
||||
///
|
||||
|
|
@ -666,7 +666,7 @@ impl Rvalue {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
|
||||
pub enum AggregateKind {
|
||||
Array(Ty),
|
||||
Tuple,
|
||||
|
|
@ -677,14 +677,14 @@ pub enum AggregateKind {
|
|||
RawPtr(Ty, Mutability),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
|
||||
pub enum Operand {
|
||||
Copy(Place),
|
||||
Move(Place),
|
||||
Constant(ConstOperand),
|
||||
}
|
||||
|
||||
#[derive(Clone, Eq, PartialEq, Serialize)]
|
||||
#[derive(Clone, Eq, PartialEq, Hash, Serialize)]
|
||||
pub struct Place {
|
||||
pub local: Local,
|
||||
/// projection out of a place (access a field, deref a pointer, etc)
|
||||
|
|
@ -697,7 +697,7 @@ impl From<Local> for Place {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
|
||||
pub struct ConstOperand {
|
||||
pub span: Span,
|
||||
pub user_ty: Option<UserTypeAnnotationIndex>,
|
||||
|
|
@ -770,7 +770,7 @@ pub enum VarDebugInfoContents {
|
|||
// ProjectionElem<Local, Ty>) and user-provided type annotations (for which the projection elements
|
||||
// are of type ProjectionElem<(), ()>).
|
||||
// In rustc_public's IR we don't need this generality, so we just use ProjectionElem for Places.
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
|
||||
pub enum ProjectionElem {
|
||||
/// Dereference projections (e.g. `*_1`) project to the address referenced by the base place.
|
||||
Deref,
|
||||
|
|
@ -913,7 +913,7 @@ impl SwitchTargets {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Serialize)]
|
||||
pub enum BorrowKind {
|
||||
/// Data must be immutable and is aliasable.
|
||||
Shared,
|
||||
|
|
@ -940,7 +940,7 @@ impl BorrowKind {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Serialize)]
|
||||
pub enum RawPtrKind {
|
||||
Mut,
|
||||
Const,
|
||||
|
|
@ -958,14 +958,14 @@ impl RawPtrKind {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Serialize)]
|
||||
pub enum MutBorrowKind {
|
||||
Default,
|
||||
TwoPhaseBorrow,
|
||||
ClosureCapture,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Serialize)]
|
||||
pub enum FakeBorrowKind {
|
||||
/// A shared (deep) borrow. Data must be immutable and is aliasable.
|
||||
Deep,
|
||||
|
|
@ -982,13 +982,13 @@ pub enum Mutability {
|
|||
Mut,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Serialize)]
|
||||
pub enum Safety {
|
||||
Safe,
|
||||
Unsafe,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Serialize)]
|
||||
pub enum PointerCoercion {
|
||||
/// Go from a fn-item type to a fn-pointer type.
|
||||
ReifyFnPointer,
|
||||
|
|
@ -1015,7 +1015,7 @@ pub enum PointerCoercion {
|
|||
Unsize,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Serialize)]
|
||||
pub enum CastKind {
|
||||
// FIXME(smir-rename): rename this to PointerExposeProvenance
|
||||
PointerExposeAddress,
|
||||
|
|
@ -1030,7 +1030,7 @@ pub enum CastKind {
|
|||
Transmute,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
|
||||
pub enum NullOp {
|
||||
/// Returns the size of a value of that type.
|
||||
SizeOf,
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ pub enum Pattern {
|
|||
}
|
||||
|
||||
/// Represents a constant in the type system
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
|
||||
pub struct TyConst {
|
||||
pub(crate) kind: TyConstKind,
|
||||
pub id: TyConstId,
|
||||
|
|
@ -140,7 +140,7 @@ impl TyConst {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
|
||||
pub enum TyConstKind {
|
||||
Param(ParamConst),
|
||||
Bound(DebruijnIndex, BoundVar),
|
||||
|
|
@ -151,11 +151,11 @@ pub enum TyConstKind {
|
|||
ZSTValue(Ty),
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Serialize)]
|
||||
pub struct TyConstId(usize);
|
||||
|
||||
/// Represents a constant in MIR
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
|
||||
pub struct MirConst {
|
||||
/// The constant kind.
|
||||
pub(crate) kind: ConstantKind,
|
||||
|
|
@ -212,17 +212,17 @@ impl MirConst {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize)]
|
||||
pub struct MirConstId(usize);
|
||||
|
||||
type Ident = Opaque;
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
|
||||
pub struct Region {
|
||||
pub kind: RegionKind,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
|
||||
pub enum RegionKind {
|
||||
ReEarlyParam(EarlyParamRegion),
|
||||
ReBound(DebruijnIndex, BoundRegion),
|
||||
|
|
@ -233,7 +233,7 @@ pub enum RegionKind {
|
|||
|
||||
pub(crate) type DebruijnIndex = u32;
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
|
||||
pub struct EarlyParamRegion {
|
||||
pub index: u32,
|
||||
pub name: Symbol,
|
||||
|
|
@ -241,7 +241,7 @@ pub struct EarlyParamRegion {
|
|||
|
||||
pub(crate) type BoundVar = u32;
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
|
||||
pub struct BoundRegion {
|
||||
pub var: BoundVar,
|
||||
pub kind: BoundRegionKind,
|
||||
|
|
@ -249,13 +249,13 @@ pub struct BoundRegion {
|
|||
|
||||
pub(crate) type UniverseIndex = u32;
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
|
||||
pub struct Placeholder<T> {
|
||||
pub universe: UniverseIndex,
|
||||
pub bound: T,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Serialize)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize)]
|
||||
pub struct Span(usize);
|
||||
|
||||
impl Debug for Span {
|
||||
|
|
@ -997,7 +997,7 @@ crate_def! {
|
|||
}
|
||||
|
||||
/// A list of generic arguments.
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
|
||||
pub struct GenericArgs(pub Vec<GenericArgKind>);
|
||||
|
||||
impl std::ops::Index<ParamTy> for GenericArgs {
|
||||
|
|
@ -1016,7 +1016,7 @@ impl std::ops::Index<ParamConst> for GenericArgs {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
|
||||
pub enum GenericArgKind {
|
||||
Lifetime(Region),
|
||||
Type(Ty),
|
||||
|
|
@ -1199,7 +1199,7 @@ pub enum BoundTyKind {
|
|||
Param(ParamDef, String),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
|
||||
pub enum BoundRegionKind {
|
||||
BrAnon,
|
||||
BrNamed(BrNamedDef, String),
|
||||
|
|
@ -1354,7 +1354,7 @@ impl Allocation {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
|
||||
pub enum ConstantKind {
|
||||
Ty(TyConst),
|
||||
Allocated(Allocation),
|
||||
|
|
@ -1365,13 +1365,13 @@ pub enum ConstantKind {
|
|||
ZeroSized,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
|
||||
pub struct ParamConst {
|
||||
pub index: u32,
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
|
||||
pub struct UnevaluatedConst {
|
||||
pub def: ConstDef,
|
||||
pub args: GenericArgs,
|
||||
|
|
|
|||
|
|
@ -34,7 +34,9 @@ jobs:
|
|||
- name: Fetch pull request ref
|
||||
run: git fetch origin "$GITHUB_REF:$GITHUB_REF"
|
||||
if: github.event_name == 'pull_request'
|
||||
- run: python3 ci/ci-util.py generate-matrix >> "$GITHUB_OUTPUT"
|
||||
- run: |
|
||||
set -eo pipefail # Needed to actually fail the job if ci-util fails
|
||||
python3 ci/ci-util.py generate-matrix | tee "$GITHUB_OUTPUT"
|
||||
id: script
|
||||
|
||||
test:
|
||||
|
|
@ -50,7 +52,6 @@ jobs:
|
|||
os: ubuntu-24.04-arm
|
||||
- target: aarch64-pc-windows-msvc
|
||||
os: windows-2025
|
||||
test_verbatim: 1
|
||||
build_only: 1
|
||||
- target: arm-unknown-linux-gnueabi
|
||||
os: ubuntu-24.04
|
||||
|
|
@ -70,8 +71,12 @@ jobs:
|
|||
os: ubuntu-24.04
|
||||
- target: powerpc64le-unknown-linux-gnu
|
||||
os: ubuntu-24.04
|
||||
- target: powerpc64le-unknown-linux-gnu
|
||||
os: ubuntu-24.04-ppc64le
|
||||
- target: riscv64gc-unknown-linux-gnu
|
||||
os: ubuntu-24.04
|
||||
- target: s390x-unknown-linux-gnu
|
||||
os: ubuntu-24.04-s390x
|
||||
- target: thumbv6m-none-eabi
|
||||
os: ubuntu-24.04
|
||||
- target: thumbv7em-none-eabi
|
||||
|
|
@ -88,10 +93,8 @@ jobs:
|
|||
os: macos-13
|
||||
- target: i686-pc-windows-msvc
|
||||
os: windows-2025
|
||||
test_verbatim: 1
|
||||
- target: x86_64-pc-windows-msvc
|
||||
os: windows-2025
|
||||
test_verbatim: 1
|
||||
- target: i686-pc-windows-gnu
|
||||
os: windows-2025
|
||||
channel: nightly-i686-gnu
|
||||
|
|
@ -102,11 +105,23 @@ jobs:
|
|||
needs: [calculate_vars]
|
||||
env:
|
||||
BUILD_ONLY: ${{ matrix.build_only }}
|
||||
TEST_VERBATIM: ${{ matrix.test_verbatim }}
|
||||
MAY_SKIP_LIBM_CI: ${{ needs.calculate_vars.outputs.may_skip_libm_ci }}
|
||||
steps:
|
||||
- name: Print $HOME
|
||||
shell: bash
|
||||
run: |
|
||||
set -x
|
||||
echo "${HOME:-not found}"
|
||||
pwd
|
||||
printenv
|
||||
- name: Print runner information
|
||||
run: uname -a
|
||||
|
||||
# Native ppc and s390x runners don't have rustup by default
|
||||
- name: Install rustup
|
||||
if: matrix.os == 'ubuntu-24.04-ppc64le' || matrix.os == 'ubuntu-24.04-s390x'
|
||||
run: sudo apt-get update && sudo apt-get install -y rustup
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install Rust (rustup)
|
||||
shell: bash
|
||||
|
|
@ -117,7 +132,12 @@ jobs:
|
|||
rustup update "$channel" --no-self-update
|
||||
rustup default "$channel"
|
||||
rustup target add "${{ matrix.target }}"
|
||||
|
||||
# Our scripts use nextest if possible. This is skipped on the native ppc
|
||||
# and s390x runners since install-action doesn't support them.
|
||||
- uses: taiki-e/install-action@nextest
|
||||
if: "!(matrix.os == 'ubuntu-24.04-ppc64le' || matrix.os == 'ubuntu-24.04-s390x')"
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
key: ${{ matrix.target }}
|
||||
|
|
@ -144,7 +164,7 @@ jobs:
|
|||
shell: bash
|
||||
- run: echo "RUST_COMPILER_RT_ROOT=$(realpath ./compiler-rt)" >> "$GITHUB_ENV"
|
||||
shell: bash
|
||||
|
||||
|
||||
- name: Download musl source
|
||||
run: ./ci/update-musl.sh
|
||||
shell: bash
|
||||
|
|
@ -256,7 +276,7 @@ jobs:
|
|||
with:
|
||||
name: ${{ env.BASELINE_NAME }}
|
||||
path: ${{ env.BASELINE_NAME }}.tar.xz
|
||||
|
||||
|
||||
- name: Run wall time benchmarks
|
||||
run: |
|
||||
# Always use the same seed for benchmarks. Ideally we should switch to a
|
||||
|
|
@ -311,8 +331,8 @@ jobs:
|
|||
timeout-minutes: 10
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install stable `rustfmt`
|
||||
run: rustup set profile minimal && rustup default stable && rustup component add rustfmt
|
||||
- name: Install nightly `rustfmt`
|
||||
run: rustup set profile minimal && rustup default nightly && rustup component add rustfmt
|
||||
- run: cargo fmt -- --check
|
||||
|
||||
extensive:
|
||||
|
|
|
|||
|
|
@ -12,12 +12,13 @@ jobs:
|
|||
if: github.repository == 'rust-lang/compiler-builtins'
|
||||
uses: rust-lang/josh-sync/.github/workflows/rustc-pull.yml@main
|
||||
with:
|
||||
github-app-id: ${{ vars.APP_CLIENT_ID }}
|
||||
# https://rust-lang.zulipchat.com/#narrow/channel/219381-t-libs/topic/compiler-builtins.20subtree.20sync.20automation/with/528482375
|
||||
zulip-stream-id: 219381
|
||||
zulip-topic: 'compiler-builtins subtree sync automation'
|
||||
zulip-bot-email: "compiler-builtins-ci-bot@rust-lang.zulipchat.com"
|
||||
zulip-bot-email: "compiler-builtins-ci-bot@rust-lang.zulipchat.com"
|
||||
pr-base-branch: master
|
||||
branch-name: rustc-pull
|
||||
secrets:
|
||||
zulip-api-token: ${{ secrets.ZULIP_API_TOKEN }}
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
github-app-secret: ${{ secrets.APP_PRIVATE_KEY }}
|
||||
|
|
|
|||
|
|
@ -37,8 +37,9 @@ default = ["compiler-builtins"]
|
|||
# implementations and also filling in unimplemented intrinsics
|
||||
c = ["dep:cc"]
|
||||
|
||||
# Workaround for the Cranelift codegen backend. Disables any implementations
|
||||
# which use inline assembly and fall back to pure Rust versions (if available).
|
||||
# For implementations where there is both a generic version and a platform-
|
||||
# specific version, use the generic version. This is meant to enable testing
|
||||
# the generic versions on all platforms.
|
||||
no-asm = []
|
||||
|
||||
# Workaround for codegen backends which haven't yet implemented `f16` and
|
||||
|
|
|
|||
|
|
@ -40,11 +40,7 @@ mod intrinsics {
|
|||
x as f64
|
||||
}
|
||||
|
||||
#[cfg(all(
|
||||
f16_enabled,
|
||||
f128_enabled,
|
||||
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
|
||||
))]
|
||||
#[cfg(all(f16_enabled, f128_enabled))]
|
||||
pub fn extendhftf(x: f16) -> f128 {
|
||||
x as f128
|
||||
}
|
||||
|
|
@ -201,11 +197,7 @@ mod intrinsics {
|
|||
|
||||
/* f128 operations */
|
||||
|
||||
#[cfg(all(
|
||||
f16_enabled,
|
||||
f128_enabled,
|
||||
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
|
||||
))]
|
||||
#[cfg(all(f16_enabled, f128_enabled))]
|
||||
pub fn trunctfhf(x: f128) -> f16 {
|
||||
x as f16
|
||||
}
|
||||
|
|
@ -220,50 +212,32 @@ mod intrinsics {
|
|||
x as f64
|
||||
}
|
||||
|
||||
#[cfg(all(
|
||||
f128_enabled,
|
||||
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
|
||||
))]
|
||||
#[cfg(f128_enabled)]
|
||||
pub fn fixtfsi(x: f128) -> i32 {
|
||||
x as i32
|
||||
}
|
||||
|
||||
#[cfg(all(
|
||||
f128_enabled,
|
||||
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
|
||||
))]
|
||||
#[cfg(f128_enabled)]
|
||||
pub fn fixtfdi(x: f128) -> i64 {
|
||||
x as i64
|
||||
}
|
||||
|
||||
#[cfg(all(
|
||||
f128_enabled,
|
||||
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
|
||||
))]
|
||||
#[cfg(f128_enabled)]
|
||||
pub fn fixtfti(x: f128) -> i128 {
|
||||
x as i128
|
||||
}
|
||||
|
||||
#[cfg(all(
|
||||
f128_enabled,
|
||||
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
|
||||
))]
|
||||
#[cfg(f128_enabled)]
|
||||
pub fn fixunstfsi(x: f128) -> u32 {
|
||||
x as u32
|
||||
}
|
||||
|
||||
#[cfg(all(
|
||||
f128_enabled,
|
||||
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
|
||||
))]
|
||||
#[cfg(f128_enabled)]
|
||||
pub fn fixunstfdi(x: f128) -> u64 {
|
||||
x as u64
|
||||
}
|
||||
|
||||
#[cfg(all(
|
||||
f128_enabled,
|
||||
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
|
||||
))]
|
||||
#[cfg(f128_enabled)]
|
||||
pub fn fixunstfti(x: f128) -> u128 {
|
||||
x as u128
|
||||
}
|
||||
|
|
@ -540,47 +514,25 @@ fn run() {
|
|||
bb(extendhfdf(bb(2.)));
|
||||
#[cfg(f16_enabled)]
|
||||
bb(extendhfsf(bb(2.)));
|
||||
#[cfg(all(
|
||||
f16_enabled,
|
||||
f128_enabled,
|
||||
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
|
||||
))]
|
||||
#[cfg(all(f16_enabled, f128_enabled))]
|
||||
bb(extendhftf(bb(2.)));
|
||||
#[cfg(f128_enabled)]
|
||||
bb(extendsftf(bb(2.)));
|
||||
bb(fixdfti(bb(2.)));
|
||||
bb(fixsfti(bb(2.)));
|
||||
#[cfg(all(
|
||||
f128_enabled,
|
||||
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
|
||||
))]
|
||||
#[cfg(f128_enabled)]
|
||||
bb(fixtfdi(bb(2.)));
|
||||
#[cfg(all(
|
||||
f128_enabled,
|
||||
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
|
||||
))]
|
||||
#[cfg(f128_enabled)]
|
||||
bb(fixtfsi(bb(2.)));
|
||||
#[cfg(all(
|
||||
f128_enabled,
|
||||
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
|
||||
))]
|
||||
#[cfg(f128_enabled)]
|
||||
bb(fixtfti(bb(2.)));
|
||||
bb(fixunsdfti(bb(2.)));
|
||||
bb(fixunssfti(bb(2.)));
|
||||
#[cfg(all(
|
||||
f128_enabled,
|
||||
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
|
||||
))]
|
||||
#[cfg(f128_enabled)]
|
||||
bb(fixunstfdi(bb(2.)));
|
||||
#[cfg(all(
|
||||
f128_enabled,
|
||||
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
|
||||
))]
|
||||
#[cfg(f128_enabled)]
|
||||
bb(fixunstfsi(bb(2.)));
|
||||
#[cfg(all(
|
||||
f128_enabled,
|
||||
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
|
||||
))]
|
||||
#[cfg(f128_enabled)]
|
||||
bb(fixunstfti(bb(2.)));
|
||||
#[cfg(f128_enabled)]
|
||||
bb(floatditf(bb(2)));
|
||||
|
|
@ -616,11 +568,7 @@ fn run() {
|
|||
bb(truncsfhf(bb(2.)));
|
||||
#[cfg(f128_enabled)]
|
||||
bb(trunctfdf(bb(2.)));
|
||||
#[cfg(all(
|
||||
f16_enabled,
|
||||
f128_enabled,
|
||||
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
|
||||
))]
|
||||
#[cfg(all(f16_enabled, f128_enabled))]
|
||||
bb(trunctfhf(bb(2.)));
|
||||
#[cfg(f128_enabled)]
|
||||
bb(trunctfsf(bb(2.)));
|
||||
|
|
|
|||
|
|
@ -365,7 +365,6 @@ float_bench! {
|
|||
|
||||
/* float -> unsigned int */
|
||||
|
||||
#[cfg(not(all(target_arch = "powerpc64", target_endian = "little")))]
|
||||
float_bench! {
|
||||
name: conv_f32_u32,
|
||||
sig: (a: f32) -> u32,
|
||||
|
|
@ -387,7 +386,6 @@ float_bench! {
|
|||
],
|
||||
}
|
||||
|
||||
#[cfg(not(all(target_arch = "powerpc64", target_endian = "little")))]
|
||||
float_bench! {
|
||||
name: conv_f32_u64,
|
||||
sig: (a: f32) -> u64,
|
||||
|
|
@ -409,7 +407,6 @@ float_bench! {
|
|||
],
|
||||
}
|
||||
|
||||
#[cfg(not(all(target_arch = "powerpc64", target_endian = "little")))]
|
||||
float_bench! {
|
||||
name: conv_f32_u128,
|
||||
sig: (a: f32) -> u128,
|
||||
|
|
@ -505,7 +502,6 @@ float_bench! {
|
|||
|
||||
/* float -> signed int */
|
||||
|
||||
#[cfg(not(all(target_arch = "powerpc64", target_endian = "little")))]
|
||||
float_bench! {
|
||||
name: conv_f32_i32,
|
||||
sig: (a: f32) -> i32,
|
||||
|
|
@ -527,7 +523,6 @@ float_bench! {
|
|||
],
|
||||
}
|
||||
|
||||
#[cfg(not(all(target_arch = "powerpc64", target_endian = "little")))]
|
||||
float_bench! {
|
||||
name: conv_f32_i64,
|
||||
sig: (a: f32) -> i64,
|
||||
|
|
@ -549,7 +544,6 @@ float_bench! {
|
|||
],
|
||||
}
|
||||
|
||||
#[cfg(not(all(target_arch = "powerpc64", target_endian = "little")))]
|
||||
float_bench! {
|
||||
name: conv_f32_i128,
|
||||
sig: (a: f32) -> i128,
|
||||
|
|
@ -666,9 +660,6 @@ pub fn float_conv() {
|
|||
conv_f64_i128(&mut criterion);
|
||||
|
||||
#[cfg(f128_enabled)]
|
||||
// FIXME: ppc64le has a sporadic overflow panic in the crate functions
|
||||
// <https://github.com/rust-lang/compiler-builtins/issues/617#issuecomment-2125914639>
|
||||
#[cfg(not(all(target_arch = "powerpc64", target_endian = "little")))]
|
||||
{
|
||||
conv_u32_f128(&mut criterion);
|
||||
conv_u64_f128(&mut criterion);
|
||||
|
|
|
|||
|
|
@ -110,9 +110,7 @@ float_bench! {
|
|||
pub fn float_extend() {
|
||||
let mut criterion = Criterion::default().configure_from_args();
|
||||
|
||||
// FIXME(#655): `f16` tests disabled until we can bootstrap symbols
|
||||
#[cfg(f16_enabled)]
|
||||
#[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))]
|
||||
{
|
||||
extend_f16_f32(&mut criterion);
|
||||
extend_f16_f64(&mut criterion);
|
||||
|
|
|
|||
|
|
@ -121,9 +121,7 @@ float_bench! {
|
|||
pub fn float_trunc() {
|
||||
let mut criterion = Criterion::default().configure_from_args();
|
||||
|
||||
// FIXME(#655): `f16` tests disabled until we can bootstrap symbols
|
||||
#[cfg(f16_enabled)]
|
||||
#[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))]
|
||||
{
|
||||
trunc_f32_f16(&mut criterion);
|
||||
trunc_f64_f16(&mut criterion);
|
||||
|
|
@ -133,11 +131,8 @@ pub fn float_trunc() {
|
|||
|
||||
#[cfg(f128_enabled)]
|
||||
{
|
||||
// FIXME(#655): `f16` tests disabled until we can bootstrap symbols
|
||||
#[cfg(f16_enabled)]
|
||||
#[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))]
|
||||
trunc_f128_f16(&mut criterion);
|
||||
|
||||
trunc_f128_f32(&mut criterion);
|
||||
trunc_f128_f64(&mut criterion);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,28 +17,14 @@ pub fn skip_sys_checks(test_name: &str) -> bool {
|
|||
"extend_f16_f32",
|
||||
"trunc_f32_f16",
|
||||
"trunc_f64_f16",
|
||||
// FIXME(#616): re-enable once fix is in nightly
|
||||
// <https://github.com/rust-lang/compiler-builtins/issues/616>
|
||||
"mul_f32",
|
||||
"mul_f64",
|
||||
];
|
||||
|
||||
// FIXME(f16_f128): error on LE ppc64. There are more tests that are cfg-ed out completely
|
||||
// in their benchmark modules due to runtime panics.
|
||||
// <https://github.com/rust-lang/compiler-builtins/issues/617#issuecomment-2125914639>
|
||||
const PPC64LE_SKIPPED: &[&str] = &["extend_f32_f128"];
|
||||
|
||||
// FIXME(f16_f128): system symbols have incorrect results
|
||||
// <https://github.com/rust-lang/compiler-builtins/issues/617#issuecomment-2125914639>
|
||||
const X86_NO_SSE_SKIPPED: &[&str] = &[
|
||||
"add_f128", "sub_f128", "mul_f128", "div_f128", "powi_f32", "powi_f64",
|
||||
];
|
||||
|
||||
// FIXME(f16_f128): Wide multiply carry bug in `compiler-rt`, re-enable when nightly no longer
|
||||
// uses `compiler-rt` version.
|
||||
// <https://github.com/llvm/llvm-project/issues/91840>
|
||||
const AARCH64_SKIPPED: &[&str] = &["mul_f128", "div_f128"];
|
||||
|
||||
// FIXME(llvm): system symbols have incorrect results on Windows
|
||||
// <https://github.com/rust-lang/compiler-builtins/issues/617#issuecomment-2121359807>
|
||||
const WINDOWS_SKIPPED: &[&str] = &[
|
||||
|
|
@ -57,19 +43,7 @@ pub fn skip_sys_checks(test_name: &str) -> bool {
|
|||
return true;
|
||||
}
|
||||
|
||||
if cfg!(all(target_arch = "powerpc64", target_endian = "little"))
|
||||
&& PPC64LE_SKIPPED.contains(&test_name)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if cfg!(all(target_arch = "x86", not(target_feature = "sse")))
|
||||
&& X86_NO_SSE_SKIPPED.contains(&test_name)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if cfg!(target_arch = "aarch64") && AARCH64_SKIPPED.contains(&test_name) {
|
||||
if cfg!(x86_no_sse) && X86_NO_SSE_SKIPPED.contains(&test_name) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ macro_rules! float_sum {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(not(all(target_arch = "x86", not(target_feature = "sse"))))]
|
||||
#[cfg(not(x86_no_sse))]
|
||||
mod float_addsub {
|
||||
use super::*;
|
||||
|
||||
|
|
@ -122,7 +122,7 @@ mod float_addsub {
|
|||
}
|
||||
|
||||
#[cfg(f128_enabled)]
|
||||
#[cfg(not(all(target_arch = "x86", not(target_feature = "sse"))))]
|
||||
#[cfg(not(x86_no_sse))]
|
||||
#[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))]
|
||||
mod float_addsub_f128 {
|
||||
use super::*;
|
||||
|
|
|
|||
|
|
@ -59,32 +59,28 @@ mod i_to_f {
|
|||
|| ((error_minus == error || error_plus == error)
|
||||
&& ((f0.to_bits() & 1) != 0))
|
||||
{
|
||||
if !cfg!(any(
|
||||
target_arch = "powerpc",
|
||||
target_arch = "powerpc64"
|
||||
)) {
|
||||
panic!(
|
||||
"incorrect rounding by {}({}): {}, ({}, {}, {}), errors ({}, {}, {})",
|
||||
stringify!($fn),
|
||||
x,
|
||||
f1.to_bits(),
|
||||
y_minus_ulp,
|
||||
y,
|
||||
y_plus_ulp,
|
||||
error_minus,
|
||||
error,
|
||||
error_plus,
|
||||
);
|
||||
}
|
||||
panic!(
|
||||
"incorrect rounding by {}({}): {}, ({}, {}, {}), errors ({}, {}, {})",
|
||||
stringify!($fn),
|
||||
x,
|
||||
f1.to_bits(),
|
||||
y_minus_ulp,
|
||||
y,
|
||||
y_plus_ulp,
|
||||
error_minus,
|
||||
error,
|
||||
error_plus,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Test against native conversion. We disable testing on all `x86` because of
|
||||
// rounding bugs with `i686`. `powerpc` also has the same rounding bug.
|
||||
// Test against native conversion.
|
||||
// FIXME(x86,ppc): the platform version has rounding bugs on i686 and
|
||||
// PowerPC64le (for PPC this only shows up in Docker, not the native runner).
|
||||
// https://github.com/rust-lang/compiler-builtins/pull/384#issuecomment-740413334
|
||||
if !Float::eq_repr(f0, f1) && !cfg!(any(
|
||||
target_arch = "x86",
|
||||
target_arch = "powerpc",
|
||||
target_arch = "powerpc64"
|
||||
all(target_arch = "powerpc64", target_endian = "little")
|
||||
)) {
|
||||
panic!(
|
||||
"{}({}): std: {:?}, builtins: {:?}",
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ macro_rules! float {
|
|||
};
|
||||
}
|
||||
|
||||
#[cfg(not(all(target_arch = "x86", not(target_feature = "sse"))))]
|
||||
#[cfg(not(x86_no_sse))]
|
||||
mod float_div {
|
||||
use super::*;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#![allow(unused_macros)]
|
||||
#![cfg_attr(f128_enabled, feature(f128))]
|
||||
#![cfg(not(all(target_arch = "x86", not(target_feature = "sse"))))]
|
||||
|
||||
#[cfg_attr(x86_no_sse, allow(unused))]
|
||||
use builtins_test::*;
|
||||
|
||||
// This is approximate because of issues related to
|
||||
|
|
@ -52,6 +52,7 @@ macro_rules! pow {
|
|||
};
|
||||
}
|
||||
|
||||
#[cfg(not(x86_no_sse))] // FIXME(i586): failure for powidf2
|
||||
pow! {
|
||||
f32, 1e-4, __powisf2, all();
|
||||
f64, 1e-12, __powidf2, all();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#![feature(decl_macro)] // so we can use pub(super)
|
||||
#![feature(macro_metavar_expr_concat)]
|
||||
#![cfg(all(target_arch = "aarch64", target_os = "linux", not(feature = "no-asm")))]
|
||||
#![cfg(all(target_arch = "aarch64", target_os = "linux"))]
|
||||
|
||||
/// Translate a byte size to a Rust type.
|
||||
macro int_ty {
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ macro_rules! float_mul {
|
|||
};
|
||||
}
|
||||
|
||||
#[cfg(not(all(target_arch = "x86", not(target_feature = "sse"))))]
|
||||
#[cfg(not(x86_no_sse))]
|
||||
mod float_mul {
|
||||
use super::*;
|
||||
|
||||
|
|
@ -126,7 +126,7 @@ mod float_mul {
|
|||
}
|
||||
|
||||
#[cfg(f128_enabled)]
|
||||
#[cfg(not(all(target_arch = "x86", not(target_feature = "sse"))))]
|
||||
#[cfg(not(x86_no_sse))]
|
||||
#[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))]
|
||||
mod float_mul_f128 {
|
||||
use super::*;
|
||||
|
|
|
|||
|
|
@ -7,10 +7,12 @@ git history.
|
|||
|
||||
import json
|
||||
import os
|
||||
import pprint
|
||||
import re
|
||||
import subprocess as sp
|
||||
import sys
|
||||
from dataclasses import dataclass
|
||||
from functools import cache
|
||||
from glob import glob
|
||||
from inspect import cleandoc
|
||||
from os import getenv
|
||||
|
|
@ -50,15 +52,6 @@ GIT = ["git", "-C", REPO_ROOT]
|
|||
DEFAULT_BRANCH = "master"
|
||||
WORKFLOW_NAME = "CI" # Workflow that generates the benchmark artifacts
|
||||
ARTIFACT_PREFIX = "baseline-icount*"
|
||||
# Place this in a PR body to skip regression checks (must be at the start of a line).
|
||||
REGRESSION_DIRECTIVE = "ci: allow-regressions"
|
||||
# Place this in a PR body to skip extensive tests
|
||||
SKIP_EXTENSIVE_DIRECTIVE = "ci: skip-extensive"
|
||||
# Place this in a PR body to allow running a large number of extensive tests. If not
|
||||
# set, this script will error out if a threshold is exceeded in order to avoid
|
||||
# accidentally spending huge amounts of CI time.
|
||||
ALLOW_MANY_EXTENSIVE_DIRECTIVE = "ci: allow-many-extensive"
|
||||
MANY_EXTENSIVE_THRESHOLD = 20
|
||||
|
||||
# Don't run exhaustive tests if these files change, even if they contaiin a function
|
||||
# definition.
|
||||
|
|
@ -70,7 +63,7 @@ IGNORE_FILES = [
|
|||
|
||||
# libm PR CI takes a long time and doesn't need to run unless relevant files have been
|
||||
# changed. Anything matching this regex pattern will trigger a run.
|
||||
TRIGGER_LIBM_PR_CI = ".*(libm|musl).*"
|
||||
TRIGGER_LIBM_CI_FILE_PAT = ".*(libm|musl).*"
|
||||
|
||||
TYPES = ["f16", "f32", "f64", "f128"]
|
||||
|
||||
|
|
@ -80,6 +73,54 @@ def eprint(*args, **kwargs):
|
|||
print(*args, file=sys.stderr, **kwargs)
|
||||
|
||||
|
||||
@dataclass(init=False)
|
||||
class PrCfg:
|
||||
"""Directives that we allow in the commit body to control test behavior.
|
||||
|
||||
These are of the form `ci: foo`, at the start of a line.
|
||||
"""
|
||||
|
||||
# Skip regression checks (must be at the start of a line).
|
||||
allow_regressions: bool = False
|
||||
# Don't run extensive tests
|
||||
skip_extensive: bool = False
|
||||
|
||||
# Allow running a large number of extensive tests. If not set, this script
|
||||
# will error out if a threshold is exceeded in order to avoid accidentally
|
||||
# spending huge amounts of CI time.
|
||||
allow_many_extensive: bool = False
|
||||
|
||||
# Max number of extensive tests to run by default
|
||||
MANY_EXTENSIVE_THRESHOLD: int = 20
|
||||
|
||||
# Run tests for `libm` that may otherwise be skipped due to no changed files.
|
||||
always_test_libm: bool = False
|
||||
|
||||
# String values of directive names
|
||||
DIR_ALLOW_REGRESSIONS: str = "allow-regressions"
|
||||
DIR_SKIP_EXTENSIVE: str = "skip-extensive"
|
||||
DIR_ALLOW_MANY_EXTENSIVE: str = "allow-many-extensive"
|
||||
DIR_TEST_LIBM: str = "test-libm"
|
||||
|
||||
def __init__(self, body: str):
|
||||
directives = re.finditer(r"^\s*ci:\s*(?P<dir_name>\S*)", body, re.MULTILINE)
|
||||
for dir in directives:
|
||||
name = dir.group("dir_name")
|
||||
if name == self.DIR_ALLOW_REGRESSIONS:
|
||||
self.allow_regressions = True
|
||||
elif name == self.DIR_SKIP_EXTENSIVE:
|
||||
self.skip_extensive = True
|
||||
elif name == self.DIR_ALLOW_MANY_EXTENSIVE:
|
||||
self.allow_many_extensive = True
|
||||
elif name == self.DIR_TEST_LIBM:
|
||||
self.always_test_libm = True
|
||||
else:
|
||||
eprint(f"Found unexpected directive `{name}`")
|
||||
exit(1)
|
||||
|
||||
pprint.pp(self)
|
||||
|
||||
|
||||
@dataclass
|
||||
class PrInfo:
|
||||
"""GitHub response for PR query"""
|
||||
|
|
@ -88,10 +129,21 @@ class PrInfo:
|
|||
commits: list[str]
|
||||
created_at: str
|
||||
number: int
|
||||
cfg: PrCfg
|
||||
|
||||
@classmethod
|
||||
def load(cls, pr_number: int | str) -> Self:
|
||||
"""For a given PR number, query the body and commit list"""
|
||||
def from_env(cls) -> Self | None:
|
||||
"""Create a PR object from the PR_NUMBER environment if set, `None` otherwise."""
|
||||
pr_env = os.environ.get("PR_NUMBER")
|
||||
if pr_env is not None and len(pr_env) > 0:
|
||||
return cls.from_pr(pr_env)
|
||||
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
@cache # Cache so we don't print info messages multiple times
|
||||
def from_pr(cls, pr_number: int | str) -> Self:
|
||||
"""For a given PR number, query the body and commit list."""
|
||||
pr_info = sp.check_output(
|
||||
[
|
||||
"gh",
|
||||
|
|
@ -104,13 +156,9 @@ class PrInfo:
|
|||
],
|
||||
text=True,
|
||||
)
|
||||
eprint("PR info:", json.dumps(pr_info, indent=4))
|
||||
return cls(**json.loads(pr_info))
|
||||
|
||||
def contains_directive(self, directive: str) -> bool:
|
||||
"""Return true if the provided directive is on a line in the PR body"""
|
||||
lines = self.body.splitlines()
|
||||
return any(line.startswith(directive) for line in lines)
|
||||
pr_json = json.loads(pr_info)
|
||||
eprint("PR info:", json.dumps(pr_json, indent=4))
|
||||
return cls(**json.loads(pr_info), cfg=PrCfg(pr_json["body"]))
|
||||
|
||||
|
||||
class FunctionDef(TypedDict):
|
||||
|
|
@ -207,26 +255,32 @@ class Context:
|
|||
"""If this is a PR and no libm files were changed, allow skipping libm
|
||||
jobs."""
|
||||
|
||||
if self.is_pr():
|
||||
return all(not re.match(TRIGGER_LIBM_PR_CI, str(f)) for f in self.changed)
|
||||
# Always run on merge CI
|
||||
if not self.is_pr():
|
||||
return False
|
||||
|
||||
return False
|
||||
pr = PrInfo.from_env()
|
||||
assert pr is not None, "Is a PR but couldn't load PrInfo"
|
||||
|
||||
# Allow opting in to libm tests
|
||||
if pr.cfg.always_test_libm:
|
||||
return False
|
||||
|
||||
# By default, run if there are any changed files matching the pattern
|
||||
return all(not re.match(TRIGGER_LIBM_CI_FILE_PAT, str(f)) for f in self.changed)
|
||||
|
||||
def emit_workflow_output(self):
|
||||
"""Create a JSON object a list items for each type's changed files, if any
|
||||
did change, and the routines that were affected by the change.
|
||||
"""
|
||||
|
||||
pr_number = os.environ.get("PR_NUMBER")
|
||||
skip_tests = False
|
||||
error_on_many_tests = False
|
||||
|
||||
if pr_number is not None and len(pr_number) > 0:
|
||||
pr = PrInfo.load(pr_number)
|
||||
skip_tests = pr.contains_directive(SKIP_EXTENSIVE_DIRECTIVE)
|
||||
error_on_many_tests = not pr.contains_directive(
|
||||
ALLOW_MANY_EXTENSIVE_DIRECTIVE
|
||||
)
|
||||
pr = PrInfo.from_env()
|
||||
if pr is not None:
|
||||
skip_tests = pr.cfg.skip_extensive
|
||||
error_on_many_tests = not pr.cfg.allow_many_extensive
|
||||
|
||||
if skip_tests:
|
||||
eprint("Skipping all extensive tests")
|
||||
|
|
@ -253,16 +307,14 @@ class Context:
|
|||
may_skip = str(self.may_skip_libm_ci()).lower()
|
||||
print(f"extensive_matrix={ext_matrix}")
|
||||
print(f"may_skip_libm_ci={may_skip}")
|
||||
eprint(f"extensive_matrix={ext_matrix}")
|
||||
eprint(f"may_skip_libm_ci={may_skip}")
|
||||
eprint(f"total extensive tests: {total_to_test}")
|
||||
|
||||
if error_on_many_tests and total_to_test > MANY_EXTENSIVE_THRESHOLD:
|
||||
if error_on_many_tests and total_to_test > PrCfg.MANY_EXTENSIVE_THRESHOLD:
|
||||
eprint(
|
||||
f"More than {MANY_EXTENSIVE_THRESHOLD} tests would be run; add"
|
||||
f" `{ALLOW_MANY_EXTENSIVE_DIRECTIVE}` to the PR body if this is"
|
||||
f"More than {PrCfg.MANY_EXTENSIVE_THRESHOLD} tests would be run; add"
|
||||
f" `{PrCfg.DIR_ALLOW_MANY_EXTENSIVE}` to the PR body if this is"
|
||||
" intentional. If this is refactoring that happens to touch a lot of"
|
||||
f" files, `{SKIP_EXTENSIVE_DIRECTIVE}` can be used instead."
|
||||
f" files, `{PrCfg.DIR_SKIP_EXTENSIVE}` can be used instead."
|
||||
)
|
||||
exit(1)
|
||||
|
||||
|
|
@ -371,8 +423,8 @@ def handle_bench_regressions(args: list[str]):
|
|||
eprint(USAGE)
|
||||
exit(1)
|
||||
|
||||
pr = PrInfo.load(pr_number)
|
||||
if pr.contains_directive(REGRESSION_DIRECTIVE):
|
||||
pr = PrInfo.from_pr(pr_number)
|
||||
if pr.cfg.allow_regressions:
|
||||
eprint("PR allows regressions")
|
||||
return
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ARG IMAGE=ubuntu:24.04
|
||||
ARG IMAGE=ubuntu:25.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ARG IMAGE=ubuntu:24.04
|
||||
ARG IMAGE=ubuntu:25.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ARG IMAGE=ubuntu:24.04
|
||||
ARG IMAGE=ubuntu:25.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ARG IMAGE=ubuntu:24.04
|
||||
ARG IMAGE=ubuntu:25.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ARG IMAGE=ubuntu:24.04
|
||||
ARG IMAGE=ubuntu:25.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ARG IMAGE=ubuntu:24.04
|
||||
ARG IMAGE=ubuntu:25.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ARG IMAGE=ubuntu:24.04
|
||||
ARG IMAGE=ubuntu:25.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ARG IMAGE=ubuntu:24.04
|
||||
ARG IMAGE=ubuntu:25.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ARG IMAGE=ubuntu:24.04
|
||||
ARG IMAGE=ubuntu:25.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ARG IMAGE=ubuntu:24.04
|
||||
ARG IMAGE=ubuntu:25.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ARG IMAGE=ubuntu:24.04
|
||||
ARG IMAGE=ubuntu:25.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ARG IMAGE=ubuntu:24.04
|
||||
ARG IMAGE=ubuntu:25.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ARG IMAGE=ubuntu:24.04
|
||||
ARG IMAGE=ubuntu:25.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ARG IMAGE=ubuntu:24.04
|
||||
ARG IMAGE=ubuntu:25.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
|
@ -12,6 +12,5 @@ ENV CARGO_TARGET_POWERPC64LE_UNKNOWN_LINUX_GNU_LINKER="$TOOLCHAIN_PREFIX"gcc \
|
|||
CARGO_TARGET_POWERPC64LE_UNKNOWN_LINUX_GNU_RUNNER=qemu-ppc64le-static \
|
||||
AR_powerpc64le_unknown_linux_gnu="$TOOLCHAIN_PREFIX"ar \
|
||||
CC_powerpc64le_unknown_linux_gnu="$TOOLCHAIN_PREFIX"gcc \
|
||||
QEMU_CPU=POWER8 \
|
||||
QEMU_LD_PREFIX=/usr/powerpc64le-linux-gnu \
|
||||
RUST_TEST_THREADS=1
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ARG IMAGE=ubuntu:24.04
|
||||
ARG IMAGE=ubuntu:25.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ARG IMAGE=ubuntu:24.04
|
||||
ARG IMAGE=ubuntu:25.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ARG IMAGE=ubuntu:24.04
|
||||
ARG IMAGE=ubuntu:25.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ARG IMAGE=ubuntu:24.04
|
||||
ARG IMAGE=ubuntu:25.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ARG IMAGE=ubuntu:24.04
|
||||
ARG IMAGE=ubuntu:25.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ARG IMAGE=ubuntu:24.04
|
||||
ARG IMAGE=ubuntu:25.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ if [ "${1:-}" = "--help" ] || [ "$#" -gt 1 ]; then
|
|||
usage: ./ci/run-docker.sh [target]
|
||||
|
||||
you can also set DOCKER_BASE_IMAGE to use something other than the default
|
||||
ubuntu:24.04 (or rustlang/rust:nightly).
|
||||
ubuntu:25.04 (or rustlang/rust:nightly).
|
||||
"
|
||||
exit
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -41,7 +41,10 @@ else
|
|||
"${test_builtins[@]}" --benches
|
||||
"${test_builtins[@]}" --benches --release
|
||||
|
||||
if [ "${TEST_VERBATIM:-}" = "1" ]; then
|
||||
# Validate that having a verbatim path for the target directory works
|
||||
# (trivial to regress using `/` in paths to build artifacts rather than
|
||||
# `Path::join`). MinGW does not currently support these paths.
|
||||
if [[ "$target" = *"windows"* ]] && [[ "$target" != *"gnu"* ]]; then
|
||||
verb_path=$(cmd.exe //C echo \\\\?\\%cd%\\builtins-test\\target2)
|
||||
"${test_builtins[@]}" --target-dir "$verb_path" --features c
|
||||
fi
|
||||
|
|
@ -161,7 +164,7 @@ else
|
|||
mflags+=(--workspace --target "$target")
|
||||
cmd=(cargo test "${mflags[@]}")
|
||||
profile_flag="--profile"
|
||||
|
||||
|
||||
# If nextest is available, use that
|
||||
command -v cargo-nextest && nextest=1 || nextest=0
|
||||
if [ "$nextest" = "1" ]; then
|
||||
|
|
@ -204,7 +207,7 @@ else
|
|||
"${cmd[@]}" "$profile_flag" release-checked --features unstable-intrinsics --benches
|
||||
|
||||
# Ensure that the routines do not panic.
|
||||
#
|
||||
#
|
||||
# `--tests` must be passed because no-panic is only enabled as a dev
|
||||
# dependency. The `release-opt` profile must be used to enable LTO and a
|
||||
# single CGU.
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
set -eux
|
||||
|
||||
url=git://git.musl-libc.org/musl
|
||||
url=https://github.com/kraj/musl.git
|
||||
ref=c47ad25ea3b484e10326f933e927c0bc8cded3da
|
||||
dst=crates/musl-math-sys/musl
|
||||
|
||||
|
|
|
|||
|
|
@ -35,8 +35,9 @@ default = ["compiler-builtins"]
|
|||
# implementations and also filling in unimplemented intrinsics
|
||||
c = ["dep:cc"]
|
||||
|
||||
# Workaround for the Cranelift codegen backend. Disables any implementations
|
||||
# which use inline assembly and fall back to pure Rust versions (if available).
|
||||
# For implementations where there is both a generic version and a platform-
|
||||
# specific version, use the generic version. This is meant to enable testing
|
||||
# the generic versions on all platforms.
|
||||
no-asm = []
|
||||
|
||||
# Workaround for codegen backends which haven't yet implemented `f16` and
|
||||
|
|
|
|||
|
|
@ -106,13 +106,6 @@ fn configure_libm(target: &Target) {
|
|||
println!("cargo:rustc-cfg=optimizations_enabled");
|
||||
}
|
||||
|
||||
// Config shorthands
|
||||
println!("cargo:rustc-check-cfg=cfg(x86_no_sse)");
|
||||
if target.arch == "x86" && !target.features.iter().any(|f| f == "sse") {
|
||||
// Shorthand to detect i586 targets
|
||||
println!("cargo:rustc-cfg=x86_no_sse");
|
||||
}
|
||||
|
||||
println!(
|
||||
"cargo:rustc-env=CFG_CARGO_FEATURES={:?}",
|
||||
target.cargo_features
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
// Configuration that is shared between `compiler_builtins` and `builtins_test`.
|
||||
|
||||
use std::process::{Command, Stdio};
|
||||
use std::{env, str};
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
@ -35,26 +34,6 @@ impl Target {
|
|||
.map(|s| s.to_lowercase().replace("_", "-"))
|
||||
.collect();
|
||||
|
||||
// Query rustc for options that Cargo does not provide env for. The bootstrap hack is used
|
||||
// to get consistent output regardless of channel (`f16`/`f128` config options are hidden
|
||||
// on stable otherwise).
|
||||
let mut cmd = Command::new(env::var("RUSTC").unwrap());
|
||||
cmd.args(["--print=cfg", "--target", &triple])
|
||||
.env("RUSTC_BOOTSTRAP", "1")
|
||||
.stderr(Stdio::inherit());
|
||||
let out = cmd
|
||||
.output()
|
||||
.unwrap_or_else(|e| panic!("failed to run `{cmd:?}`: {e}"));
|
||||
let rustc_cfg = str::from_utf8(&out.stdout).unwrap();
|
||||
|
||||
// If we couldn't query `rustc` (e.g. a custom JSON target was used), make the safe
|
||||
// choice and leave `f16` and `f128` disabled.
|
||||
let rustc_output_ok = out.status.success();
|
||||
let reliable_f128 =
|
||||
rustc_output_ok && rustc_cfg.lines().any(|l| l == "target_has_reliable_f128");
|
||||
let reliable_f16 =
|
||||
rustc_output_ok && rustc_cfg.lines().any(|l| l == "target_has_reliable_f16");
|
||||
|
||||
Self {
|
||||
triple,
|
||||
triple_split,
|
||||
|
|
@ -74,8 +53,10 @@ impl Target {
|
|||
.split(",")
|
||||
.map(ToOwned::to_owned)
|
||||
.collect(),
|
||||
reliable_f128,
|
||||
reliable_f16,
|
||||
// Note that these are unstable options, so only show up with the nightly compiler or
|
||||
// with `RUSTC_BOOTSTRAP=1` (which is required to use the types anyway).
|
||||
reliable_f128: env::var_os("CARGO_CFG_TARGET_HAS_RELIABLE_F128").is_some(),
|
||||
reliable_f16: env::var_os("CARGO_CFG_TARGET_HAS_RELIABLE_F16").is_some(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -100,6 +81,13 @@ pub fn configure_aliases(target: &Target) {
|
|||
println!("cargo:rustc-cfg=thumb_1")
|
||||
}
|
||||
|
||||
// Config shorthands
|
||||
println!("cargo:rustc-check-cfg=cfg(x86_no_sse)");
|
||||
if target.arch == "x86" && !target.features.iter().any(|f| f == "sse") {
|
||||
// Shorthand to detect i586 targets
|
||||
println!("cargo:rustc-cfg=x86_no_sse");
|
||||
}
|
||||
|
||||
/* Not all backends support `f16` and `f128` to the same level on all architectures, so we
|
||||
* need to disable things if the compiler may crash. See configuration at:
|
||||
* * https://github.com/rust-lang/rust/blob/c65dccabacdfd6c8a7f7439eba13422fdd89b91e/compiler/rustc_codegen_llvm/src/llvm_util.rs#L367-L432
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use core::intrinsics;
|
|||
|
||||
intrinsics! {
|
||||
#[unsafe(naked)]
|
||||
#[cfg(all(target_os = "uefi", not(feature = "no-asm")))]
|
||||
#[cfg(target_os = "uefi")]
|
||||
pub unsafe extern "custom" fn __chkstk() {
|
||||
core::arch::naked_asm!(
|
||||
".p2align 2",
|
||||
|
|
|
|||
|
|
@ -6,9 +6,6 @@
|
|||
//! which is supported on the current CPU.
|
||||
//! See <https://community.arm.com/arm-community-blogs/b/tools-software-ides-blog/posts/making-the-most-of-the-arm-architecture-in-gcc-10#:~:text=out%20of%20line%20atomics> for more discussion.
|
||||
//!
|
||||
//! Currently we only support LL/SC, because LSE requires `getauxval` from libc in order to do runtime detection.
|
||||
//! Use the `compiler-rt` intrinsics if you want LSE support.
|
||||
//!
|
||||
//! Ported from `aarch64/lse.S` in LLVM's compiler-rt.
|
||||
//!
|
||||
//! Generate functions for each of the following symbols:
|
||||
|
|
@ -24,7 +21,18 @@
|
|||
//! We do something similar, but with macro arguments.
|
||||
#![cfg_attr(feature = "c", allow(unused_macros))] // avoid putting the macros into a submodule
|
||||
|
||||
// We don't do runtime dispatch so we don't have to worry about the `__aarch64_have_lse_atomics` global ctor.
|
||||
use core::sync::atomic::{AtomicU8, Ordering};
|
||||
|
||||
/// non-zero if the host supports LSE atomics.
|
||||
static HAVE_LSE_ATOMICS: AtomicU8 = AtomicU8::new(0);
|
||||
|
||||
intrinsics! {
|
||||
/// Call to enable LSE in outline atomic operations. The caller must verify
|
||||
/// LSE operations are supported.
|
||||
pub extern "C" fn __rust_enable_lse() {
|
||||
HAVE_LSE_ATOMICS.store(1, Ordering::Relaxed);
|
||||
}
|
||||
}
|
||||
|
||||
/// Translate a byte size to a Rust type.
|
||||
#[rustfmt::skip]
|
||||
|
|
@ -45,6 +53,7 @@ macro_rules! reg {
|
|||
(2, $num:literal) => { concat!("w", $num) };
|
||||
(4, $num:literal) => { concat!("w", $num) };
|
||||
(8, $num:literal) => { concat!("x", $num) };
|
||||
(16, $num:literal) => { concat!("x", $num) };
|
||||
}
|
||||
|
||||
/// Given an atomic ordering, translate it to the acquire suffix for the lxdr aarch64 ASM instruction.
|
||||
|
|
@ -126,6 +135,41 @@ macro_rules! stxp {
|
|||
};
|
||||
}
|
||||
|
||||
// If supported, perform the requested LSE op and return, or fallthrough.
|
||||
macro_rules! try_lse_op {
|
||||
($op: literal, $ordering:ident, $bytes:tt, $($reg:literal,)* [ $mem:ident ] ) => {
|
||||
concat!(
|
||||
".arch_extension lse; ",
|
||||
"adrp x16, {have_lse}; ",
|
||||
"ldrb w16, [x16, :lo12:{have_lse}]; ",
|
||||
"cbz w16, 8f; ",
|
||||
// LSE_OP s(reg),* [$mem]
|
||||
concat!(lse!($op, $ordering, $bytes), $( " ", reg!($bytes, $reg), ", " ,)* "[", stringify!($mem), "]; ",),
|
||||
"ret; ",
|
||||
"8:"
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
// Translate memory ordering to the LSE suffix
|
||||
#[rustfmt::skip]
|
||||
macro_rules! lse_mem_sfx {
|
||||
(Relaxed) => { "" };
|
||||
(Acquire) => { "a" };
|
||||
(Release) => { "l" };
|
||||
(AcqRel) => { "al" };
|
||||
}
|
||||
|
||||
// Generate the aarch64 LSE operation for memory ordering and width
|
||||
macro_rules! lse {
|
||||
($op:literal, $order:ident, 16) => {
|
||||
concat!($op, "p", lse_mem_sfx!($order))
|
||||
};
|
||||
($op:literal, $order:ident, $bytes:tt) => {
|
||||
concat!($op, lse_mem_sfx!($order), size!($bytes))
|
||||
};
|
||||
}
|
||||
|
||||
/// See <https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicI8.html#method.compare_and_swap>.
|
||||
macro_rules! compare_and_swap {
|
||||
($ordering:ident, $bytes:tt, $name:ident) => {
|
||||
|
|
@ -137,7 +181,9 @@ macro_rules! compare_and_swap {
|
|||
) -> int_ty!($bytes) {
|
||||
// We can't use `AtomicI8::compare_and_swap`; we *are* compare_and_swap.
|
||||
core::arch::naked_asm! {
|
||||
// UXT s(tmp0), s(0)
|
||||
// CAS s(0), s(1), [x2]; if LSE supported.
|
||||
try_lse_op!("cas", $ordering, $bytes, 0, 1, [x2]),
|
||||
// UXT s(tmp0), s(0)
|
||||
concat!(uxt!($bytes), " ", reg!($bytes, 16), ", ", reg!($bytes, 0)),
|
||||
"0:",
|
||||
// LDXR s(0), [x2]
|
||||
|
|
@ -150,6 +196,7 @@ macro_rules! compare_and_swap {
|
|||
"cbnz w17, 0b",
|
||||
"1:",
|
||||
"ret",
|
||||
have_lse = sym crate::aarch64_linux::HAVE_LSE_ATOMICS,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -166,6 +213,8 @@ macro_rules! compare_and_swap_i128 {
|
|||
expected: i128, desired: i128, ptr: *mut i128
|
||||
) -> i128 {
|
||||
core::arch::naked_asm! {
|
||||
// CASP x0, x1, x2, x3, [x4]; if LSE supported.
|
||||
try_lse_op!("cas", $ordering, 16, 0, 1, 2, 3, [x4]),
|
||||
"mov x16, x0",
|
||||
"mov x17, x1",
|
||||
"0:",
|
||||
|
|
@ -179,6 +228,7 @@ macro_rules! compare_and_swap_i128 {
|
|||
"cbnz w15, 0b",
|
||||
"1:",
|
||||
"ret",
|
||||
have_lse = sym crate::aarch64_linux::HAVE_LSE_ATOMICS,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -195,6 +245,8 @@ macro_rules! swap {
|
|||
left: int_ty!($bytes), right_ptr: *mut int_ty!($bytes)
|
||||
) -> int_ty!($bytes) {
|
||||
core::arch::naked_asm! {
|
||||
// SWP s(0), s(0), [x1]; if LSE supported.
|
||||
try_lse_op!("swp", $ordering, $bytes, 0, 0, [x1]),
|
||||
// mov s(tmp0), s(0)
|
||||
concat!("mov ", reg!($bytes, 16), ", ", reg!($bytes, 0)),
|
||||
"0:",
|
||||
|
|
@ -204,6 +256,7 @@ macro_rules! swap {
|
|||
concat!(stxr!($ordering, $bytes), " w17, ", reg!($bytes, 16), ", [x1]"),
|
||||
"cbnz w17, 0b",
|
||||
"ret",
|
||||
have_lse = sym crate::aarch64_linux::HAVE_LSE_ATOMICS,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -212,7 +265,7 @@ macro_rules! swap {
|
|||
|
||||
/// See (e.g.) <https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicI8.html#method.fetch_add>.
|
||||
macro_rules! fetch_op {
|
||||
($ordering:ident, $bytes:tt, $name:ident, $op:literal) => {
|
||||
($ordering:ident, $bytes:tt, $name:ident, $op:literal, $lse_op:literal) => {
|
||||
intrinsics! {
|
||||
#[maybe_use_optimized_c_shim]
|
||||
#[unsafe(naked)]
|
||||
|
|
@ -220,6 +273,8 @@ macro_rules! fetch_op {
|
|||
val: int_ty!($bytes), ptr: *mut int_ty!($bytes)
|
||||
) -> int_ty!($bytes) {
|
||||
core::arch::naked_asm! {
|
||||
// LSEOP s(0), s(0), [x1]; if LSE supported.
|
||||
try_lse_op!($lse_op, $ordering, $bytes, 0, 0, [x1]),
|
||||
// mov s(tmp0), s(0)
|
||||
concat!("mov ", reg!($bytes, 16), ", ", reg!($bytes, 0)),
|
||||
"0:",
|
||||
|
|
@ -231,6 +286,7 @@ macro_rules! fetch_op {
|
|||
concat!(stxr!($ordering, $bytes), " w15, ", reg!($bytes, 17), ", [x1]"),
|
||||
"cbnz w15, 0b",
|
||||
"ret",
|
||||
have_lse = sym crate::aarch64_linux::HAVE_LSE_ATOMICS,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -240,25 +296,25 @@ macro_rules! fetch_op {
|
|||
// We need a single macro to pass to `foreach_ldadd`.
|
||||
macro_rules! add {
|
||||
($ordering:ident, $bytes:tt, $name:ident) => {
|
||||
fetch_op! { $ordering, $bytes, $name, "add" }
|
||||
fetch_op! { $ordering, $bytes, $name, "add", "ldadd" }
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! and {
|
||||
($ordering:ident, $bytes:tt, $name:ident) => {
|
||||
fetch_op! { $ordering, $bytes, $name, "bic" }
|
||||
fetch_op! { $ordering, $bytes, $name, "bic", "ldclr" }
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! xor {
|
||||
($ordering:ident, $bytes:tt, $name:ident) => {
|
||||
fetch_op! { $ordering, $bytes, $name, "eor" }
|
||||
fetch_op! { $ordering, $bytes, $name, "eor", "ldeor" }
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! or {
|
||||
($ordering:ident, $bytes:tt, $name:ident) => {
|
||||
fetch_op! { $ordering, $bytes, $name, "orr" }
|
||||
fetch_op! { $ordering, $bytes, $name, "orr", "ldset" }
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
#![cfg(not(feature = "no-asm"))]
|
||||
|
||||
// Interfaces used by naked trampolines.
|
||||
// SAFETY: these are defined in compiler-builtins
|
||||
unsafe extern "C" {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
#![cfg(not(feature = "no-asm"))]
|
||||
|
||||
use core::arch::global_asm;
|
||||
|
||||
global_asm!(include_str!("hexagon/func_macro.s"), options(raw));
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ pub mod arm;
|
|||
#[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))]
|
||||
pub mod aarch64;
|
||||
|
||||
#[cfg(all(target_arch = "aarch64", target_os = "linux", not(feature = "no-asm"),))]
|
||||
#[cfg(all(target_arch = "aarch64", target_os = "linux"))]
|
||||
pub mod aarch64_linux;
|
||||
|
||||
#[cfg(all(
|
||||
|
|
|
|||
|
|
@ -44,8 +44,6 @@
|
|||
#![cfg(not(feature = "mangled-names"))]
|
||||
// Windows and Cygwin already has builtins to do this.
|
||||
#![cfg(not(any(windows, target_os = "cygwin")))]
|
||||
// All these builtins require assembly
|
||||
#![cfg(not(feature = "no-asm"))]
|
||||
// We only define stack probing for these architectures today.
|
||||
#![cfg(any(target_arch = "x86_64", target_arch = "x86"))]
|
||||
|
||||
|
|
|
|||
|
|
@ -9,10 +9,7 @@ use core::intrinsics;
|
|||
|
||||
intrinsics! {
|
||||
#[unsafe(naked)]
|
||||
#[cfg(all(
|
||||
any(all(windows, target_env = "gnu"), target_os = "uefi"),
|
||||
not(feature = "no-asm")
|
||||
))]
|
||||
#[cfg(any(all(windows, target_env = "gnu"), target_os = "uefi"))]
|
||||
pub unsafe extern "custom" fn __chkstk() {
|
||||
core::arch::naked_asm!(
|
||||
"jmp {}", // Jump to __alloca since fallthrough may be unreliable"
|
||||
|
|
@ -21,10 +18,7 @@ intrinsics! {
|
|||
}
|
||||
|
||||
#[unsafe(naked)]
|
||||
#[cfg(all(
|
||||
any(all(windows, target_env = "gnu"), target_os = "uefi"),
|
||||
not(feature = "no-asm")
|
||||
))]
|
||||
#[cfg(any(all(windows, target_env = "gnu"), target_os = "uefi"))]
|
||||
pub unsafe extern "custom" fn _alloca() {
|
||||
// __chkstk and _alloca are the same function
|
||||
core::arch::naked_asm!(
|
||||
|
|
|
|||
|
|
@ -9,14 +9,7 @@ use core::intrinsics;
|
|||
|
||||
intrinsics! {
|
||||
#[unsafe(naked)]
|
||||
#[cfg(all(
|
||||
any(
|
||||
all(windows, target_env = "gnu"),
|
||||
target_os = "cygwin",
|
||||
target_os = "uefi"
|
||||
),
|
||||
not(feature = "no-asm")
|
||||
))]
|
||||
#[cfg(any(all(windows, target_env = "gnu"), target_os = "cygwin", target_os = "uefi"))]
|
||||
pub unsafe extern "custom" fn ___chkstk_ms() {
|
||||
core::arch::naked_asm!(
|
||||
"push %rcx",
|
||||
|
|
|
|||
|
|
@ -40,8 +40,6 @@ macro_rules! functions {
|
|||
) => {
|
||||
// Run a simple check to ensure we can link and call the function without crashing.
|
||||
#[test]
|
||||
// FIXME(#309): LE PPC crashes calling some musl functions
|
||||
#[cfg_attr(all(target_arch = "powerpc64", target_endian = "little"), ignore)]
|
||||
fn $name() {
|
||||
<fn($($aty),+) -> $rty>::check(super::$name);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,8 +5,7 @@ edition = "2024"
|
|||
publish = false
|
||||
|
||||
[dependencies]
|
||||
# FIXME: used as a git dependency since the latest release does not support wasm
|
||||
object = { git = "https://github.com/gimli-rs/object.git", rev = "013fac75da56a684377af4151b8164b78c1790e0" }
|
||||
object = "0.37.1"
|
||||
serde_json = "1.0.140"
|
||||
|
||||
[features]
|
||||
|
|
|
|||
|
|
@ -271,18 +271,6 @@ impl MaybeOverride<(f32,)> for SpecialCase {
|
|||
|
||||
impl MaybeOverride<(f64,)> for SpecialCase {
|
||||
fn check_float<F: Float>(input: (f64,), actual: F, expected: F, ctx: &CheckCtx) -> CheckAction {
|
||||
if cfg!(x86_no_sse)
|
||||
&& ctx.base_name == BaseName::Ceil
|
||||
&& ctx.basis == CheckBasis::Musl
|
||||
&& input.0 < 0.0
|
||||
&& input.0 > -1.0
|
||||
&& expected == F::ZERO
|
||||
&& actual == F::ZERO
|
||||
{
|
||||
// musl returns -0.0, we return +0.0
|
||||
return XFAIL("i586 ceil signed zero");
|
||||
}
|
||||
|
||||
if cfg!(x86_no_sse)
|
||||
&& (ctx.base_name == BaseName::Rint || ctx.base_name == BaseName::Roundeven)
|
||||
&& (expected - actual).abs() <= F::ONE
|
||||
|
|
@ -292,16 +280,6 @@ impl MaybeOverride<(f64,)> for SpecialCase {
|
|||
return XFAIL("i586 rint rounding mode");
|
||||
}
|
||||
|
||||
if cfg!(x86_no_sse)
|
||||
&& (ctx.fn_ident == Identifier::Ceil || ctx.fn_ident == Identifier::Floor)
|
||||
&& expected.eq_repr(F::NEG_ZERO)
|
||||
&& actual.eq_repr(F::ZERO)
|
||||
{
|
||||
// FIXME: the x87 implementations do not keep the distinction between -0.0 and 0.0.
|
||||
// See https://github.com/rust-lang/libm/pull/404#issuecomment-2572399955
|
||||
return XFAIL("i586 ceil/floor signed zero");
|
||||
}
|
||||
|
||||
if cfg!(x86_no_sse)
|
||||
&& (ctx.fn_ident == Identifier::Exp10 || ctx.fn_ident == Identifier::Exp2)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
// Configuration shared with both libm and libm-test
|
||||
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
use std::process::{Command, Stdio};
|
||||
use std::{env, str};
|
||||
|
||||
#[derive(Debug)]
|
||||
#[allow(dead_code)]
|
||||
pub struct Config {
|
||||
pub manifest_dir: PathBuf,
|
||||
|
|
@ -33,26 +33,6 @@ impl Config {
|
|||
.map(|s| s.to_lowercase().replace("_", "-"))
|
||||
.collect();
|
||||
|
||||
// Query rustc for options that Cargo does not provide env for. The bootstrap hack is used
|
||||
// to get consistent output regardless of channel (`f16`/`f128` config options are hidden
|
||||
// on stable otherwise).
|
||||
let mut cmd = Command::new(env::var("RUSTC").unwrap());
|
||||
cmd.args(["--print=cfg", "--target", &target_triple])
|
||||
.env("RUSTC_BOOTSTRAP", "1")
|
||||
.stderr(Stdio::inherit());
|
||||
let out = cmd
|
||||
.output()
|
||||
.unwrap_or_else(|e| panic!("failed to run `{cmd:?}`: {e}"));
|
||||
let rustc_cfg = str::from_utf8(&out.stdout).unwrap();
|
||||
|
||||
// If we couldn't query `rustc` (e.g. a custom JSON target was used), make the safe
|
||||
// choice and leave `f16` and `f128` disabled.
|
||||
let rustc_output_ok = out.status.success();
|
||||
let reliable_f128 =
|
||||
rustc_output_ok && rustc_cfg.lines().any(|l| l == "target_has_reliable_f128");
|
||||
let reliable_f16 =
|
||||
rustc_output_ok && rustc_cfg.lines().any(|l| l == "target_has_reliable_f16");
|
||||
|
||||
Self {
|
||||
target_triple,
|
||||
manifest_dir: PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()),
|
||||
|
|
@ -66,8 +46,10 @@ impl Config {
|
|||
target_string: env::var("TARGET").unwrap(),
|
||||
target_vendor: env::var("CARGO_CFG_TARGET_VENDOR").unwrap(),
|
||||
target_features,
|
||||
reliable_f128,
|
||||
reliable_f16,
|
||||
// Note that these are unstable options, so only show up with the nightly compiler or
|
||||
// with `RUSTC_BOOTSTRAP=1` (which is required to use the types anyway).
|
||||
reliable_f128: env::var_os("CARGO_CFG_TARGET_HAS_RELIABLE_F128").is_some(),
|
||||
reliable_f16: env::var_os("CARGO_CFG_TARGET_HAS_RELIABLE_F16").is_some(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ fn r(z: f64) -> f64 {
|
|||
/// Computes the inverse cosine (arc cosine) of the input value.
|
||||
/// Arguments must be in the range -1 to 1.
|
||||
/// Returns values in radians, in the range of 0 to pi.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn acos(x: f64) -> f64 {
|
||||
let x1p_120f = f64::from_bits(0x3870000000000000); // 0x1p-120 === 2 ^ -120
|
||||
let z: f64;
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ fn r(z: f32) -> f32 {
|
|||
/// Computes the inverse cosine (arc cosine) of the input value.
|
||||
/// Arguments must be in the range -1 to 1.
|
||||
/// Returns values in radians, in the range of 0 to pi.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn acosf(x: f32) -> f32 {
|
||||
let x1p_120 = f32::from_bits(0x03800000); // 0x1p-120 === 2 ^ (-120)
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ const LN2: f64 = 0.693147180559945309417232121458176568; /* 0x3fe62e42, 0xfefa3
|
|||
/// Calculates the inverse hyperbolic cosine of `x`.
|
||||
/// Is defined as `log(x + sqrt(x*x-1))`.
|
||||
/// `x` must be a number greater than or equal to 1.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn acosh(x: f64) -> f64 {
|
||||
let u = x.to_bits();
|
||||
let e = ((u >> 52) as usize) & 0x7ff;
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ const LN2: f32 = 0.693147180559945309417232121458176568;
|
|||
/// Calculates the inverse hyperbolic cosine of `x`.
|
||||
/// Is defined as `log(x + sqrt(x*x-1))`.
|
||||
/// `x` must be a number greater than or equal to 1.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn acoshf(x: f32) -> f32 {
|
||||
let u = x.to_bits();
|
||||
let a = u & 0x7fffffff;
|
||||
|
|
|
|||
|
|
@ -1,37 +1,62 @@
|
|||
//! Architecture-specific support for x86-32 without SSE2
|
||||
//!
|
||||
//! We use an alternative implementation on x86, because the
|
||||
//! main implementation fails with the x87 FPU used by
|
||||
//! debian i386, probably due to excess precision issues.
|
||||
//!
|
||||
//! See https://github.com/rust-lang/compiler-builtins/pull/976 for discussion on why these
|
||||
//! functions are implemented in this way.
|
||||
|
||||
use super::super::fabs;
|
||||
|
||||
/// Use an alternative implementation on x86, because the
|
||||
/// main implementation fails with the x87 FPU used by
|
||||
/// debian i386, probably due to excess precision issues.
|
||||
/// Basic implementation taken from https://github.com/rust-lang/libm/issues/219.
|
||||
pub fn ceil(x: f64) -> f64 {
|
||||
if fabs(x).to_bits() < 4503599627370496.0_f64.to_bits() {
|
||||
let truncated = x as i64 as f64;
|
||||
if truncated < x {
|
||||
return truncated + 1.0;
|
||||
} else {
|
||||
return truncated;
|
||||
}
|
||||
} else {
|
||||
return x;
|
||||
pub fn ceil(mut x: f64) -> f64 {
|
||||
unsafe {
|
||||
core::arch::asm!(
|
||||
"fld qword ptr [{x}]",
|
||||
// Save the FPU control word, using `x` as scratch space.
|
||||
"fstcw [{x}]",
|
||||
// Set rounding control to 0b10 (+∞).
|
||||
"mov word ptr [{x} + 2], 0x0b7f",
|
||||
"fldcw [{x} + 2]",
|
||||
// Round.
|
||||
"frndint",
|
||||
// Restore FPU control word.
|
||||
"fldcw [{x}]",
|
||||
// Save rounded value to memory.
|
||||
"fstp qword ptr [{x}]",
|
||||
x = in(reg) &mut x,
|
||||
// All the x87 FPU stack is used, all registers must be clobbered
|
||||
out("st(0)") _, out("st(1)") _,
|
||||
out("st(2)") _, out("st(3)") _,
|
||||
out("st(4)") _, out("st(5)") _,
|
||||
out("st(6)") _, out("st(7)") _,
|
||||
options(nostack),
|
||||
);
|
||||
}
|
||||
x
|
||||
}
|
||||
|
||||
/// Use an alternative implementation on x86, because the
|
||||
/// main implementation fails with the x87 FPU used by
|
||||
/// debian i386, probably due to excess precision issues.
|
||||
/// Basic implementation taken from https://github.com/rust-lang/libm/issues/219.
|
||||
pub fn floor(x: f64) -> f64 {
|
||||
if fabs(x).to_bits() < 4503599627370496.0_f64.to_bits() {
|
||||
let truncated = x as i64 as f64;
|
||||
if truncated > x {
|
||||
return truncated - 1.0;
|
||||
} else {
|
||||
return truncated;
|
||||
}
|
||||
} else {
|
||||
return x;
|
||||
pub fn floor(mut x: f64) -> f64 {
|
||||
unsafe {
|
||||
core::arch::asm!(
|
||||
"fld qword ptr [{x}]",
|
||||
// Save the FPU control word, using `x` as scratch space.
|
||||
"fstcw [{x}]",
|
||||
// Set rounding control to 0b01 (-∞).
|
||||
"mov word ptr [{x} + 2], 0x077f",
|
||||
"fldcw [{x} + 2]",
|
||||
// Round.
|
||||
"frndint",
|
||||
// Restore FPU control word.
|
||||
"fldcw [{x}]",
|
||||
// Save rounded value to memory.
|
||||
"fstp qword ptr [{x}]",
|
||||
x = in(reg) &mut x,
|
||||
// All the x87 FPU stack is used, all registers must be clobbered
|
||||
out("st(0)") _, out("st(1)") _,
|
||||
out("st(2)") _, out("st(3)") _,
|
||||
out("st(4)") _, out("st(5)") _,
|
||||
out("st(6)") _, out("st(7)") _,
|
||||
options(nostack),
|
||||
);
|
||||
}
|
||||
x
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ fn comp_r(z: f64) -> f64 {
|
|||
/// Computes the inverse sine (arc sine) of the argument `x`.
|
||||
/// Arguments to asin must be in the range -1 to 1.
|
||||
/// Returns values in radians, in the range of -pi/2 to pi/2.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn asin(mut x: f64) -> f64 {
|
||||
let z: f64;
|
||||
let r: f64;
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ fn r(z: f32) -> f32 {
|
|||
/// Computes the inverse sine (arc sine) of the argument `x`.
|
||||
/// Arguments to asin must be in the range -1 to 1.
|
||||
/// Returns values in radians, in the range of -pi/2 to pi/2.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn asinf(mut x: f32) -> f32 {
|
||||
let x1p_120 = f64::from_bits(0x3870000000000000); // 0x1p-120 === 2 ^ (-120)
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ const LN2: f64 = 0.693147180559945309417232121458176568; /* 0x3fe62e42, 0xfefa3
|
|||
///
|
||||
/// Calculates the inverse hyperbolic sine of `x`.
|
||||
/// Is defined as `sgn(x)*log(|x|+sqrt(x*x+1))`.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn asinh(mut x: f64) -> f64 {
|
||||
let mut u = x.to_bits();
|
||||
let e = ((u >> 52) as usize) & 0x7ff;
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ const LN2: f32 = 0.693147180559945309417232121458176568;
|
|||
///
|
||||
/// Calculates the inverse hyperbolic sine of `x`.
|
||||
/// Is defined as `sgn(x)*log(|x|+sqrt(x*x+1))`.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn asinhf(mut x: f32) -> f32 {
|
||||
let u = x.to_bits();
|
||||
let i = u & 0x7fffffff;
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ const AT: [f64; 11] = [
|
|||
///
|
||||
/// Computes the inverse tangent (arc tangent) of the input value.
|
||||
/// Returns a value in radians, in the range of -pi/2 to pi/2.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn atan(x: f64) -> f64 {
|
||||
let mut x = x;
|
||||
let mut ix = (x.to_bits() >> 32) as u32;
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ const PI_LO: f64 = 1.2246467991473531772E-16; /* 0x3CA1A626, 0x33145C07 */
|
|||
/// Computes the inverse tangent (arc tangent) of `y/x`.
|
||||
/// Produces the correct result even for angles near pi/2 or -pi/2 (that is, when `x` is near 0).
|
||||
/// Returns a value in radians, in the range of -pi to pi.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn atan2(y: f64, x: f64) -> f64 {
|
||||
if x.is_nan() || y.is_nan() {
|
||||
return x + y;
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ const PI_LO: f32 = -8.7422776573e-08; /* 0xb3bbbd2e */
|
|||
/// Computes the inverse tangent (arc tangent) of `y/x`.
|
||||
/// Produces the correct result even for angles near pi/2 or -pi/2 (that is, when `x` is near 0).
|
||||
/// Returns a value in radians, in the range of -pi to pi.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn atan2f(y: f32, x: f32) -> f32 {
|
||||
if x.is_nan() || y.is_nan() {
|
||||
return x + y;
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ const A_T: [f32; 5] = [
|
|||
///
|
||||
/// Computes the inverse tangent (arc tangent) of the input value.
|
||||
/// Returns a value in radians, in the range of -pi/2 to pi/2.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn atanf(mut x: f32) -> f32 {
|
||||
let x1p_120 = f32::from_bits(0x03800000); // 0x1p-120 === 2 ^ (-120)
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use super::log1p;
|
|||
///
|
||||
/// Calculates the inverse hyperbolic tangent of `x`.
|
||||
/// Is defined as `log((1+x)/(1-x))/2 = log1p(2x/(1-x))/2`.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn atanh(x: f64) -> f64 {
|
||||
let u = x.to_bits();
|
||||
let e = ((u >> 52) as usize) & 0x7ff;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use super::log1pf;
|
|||
///
|
||||
/// Calculates the inverse hyperbolic tangent of `x`.
|
||||
/// Is defined as `log((1+x)/(1-x))/2 = log1p(2x/(1-x))/2`.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn atanhf(mut x: f32) -> f32 {
|
||||
let mut u = x.to_bits();
|
||||
let sign = (u >> 31) != 0;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use super::Float;
|
|||
use super::support::{FpResult, Round, cold_path};
|
||||
|
||||
/// Compute the cube root of the argument.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn cbrt(x: f64) -> f64 {
|
||||
cbrt_round(x, Round::Nearest).val
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ const B2: u32 = 642849266; /* B2 = (127-127.0/3-24/3-0.03306235651)*2**23 */
|
|||
/// Cube root (f32)
|
||||
///
|
||||
/// Computes the cube root of the argument.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn cbrtf(x: f32) -> f32 {
|
||||
let x1p24 = f32::from_bits(0x4b800000); // 0x1p24f === 2 ^ 24
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
///
|
||||
/// Finds the nearest integer greater than or equal to `x`.
|
||||
#[cfg(f16_enabled)]
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn ceilf16(x: f16) -> f16 {
|
||||
super::generic::ceil(x)
|
||||
}
|
||||
|
|
@ -10,7 +10,7 @@ pub fn ceilf16(x: f16) -> f16 {
|
|||
/// Ceil (f32)
|
||||
///
|
||||
/// Finds the nearest integer greater than or equal to `x`.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn ceilf(x: f32) -> f32 {
|
||||
select_implementation! {
|
||||
name: ceilf,
|
||||
|
|
@ -24,7 +24,7 @@ pub fn ceilf(x: f32) -> f32 {
|
|||
/// Ceil (f64)
|
||||
///
|
||||
/// Finds the nearest integer greater than or equal to `x`.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn ceil(x: f64) -> f64 {
|
||||
select_implementation! {
|
||||
name: ceil,
|
||||
|
|
@ -40,7 +40,7 @@ pub fn ceil(x: f64) -> f64 {
|
|||
///
|
||||
/// Finds the nearest integer greater than or equal to `x`.
|
||||
#[cfg(f128_enabled)]
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn ceilf128(x: f128) -> f128 {
|
||||
super::generic::ceil(x)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
/// Constructs a number with the magnitude (absolute value) of its
|
||||
/// first argument, `x`, and the sign of its second argument, `y`.
|
||||
#[cfg(f16_enabled)]
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn copysignf16(x: f16, y: f16) -> f16 {
|
||||
super::generic::copysign(x, y)
|
||||
}
|
||||
|
|
@ -12,7 +12,7 @@ pub fn copysignf16(x: f16, y: f16) -> f16 {
|
|||
///
|
||||
/// Constructs a number with the magnitude (absolute value) of its
|
||||
/// first argument, `x`, and the sign of its second argument, `y`.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn copysignf(x: f32, y: f32) -> f32 {
|
||||
super::generic::copysign(x, y)
|
||||
}
|
||||
|
|
@ -21,7 +21,7 @@ pub fn copysignf(x: f32, y: f32) -> f32 {
|
|||
///
|
||||
/// Constructs a number with the magnitude (absolute value) of its
|
||||
/// first argument, `x`, and the sign of its second argument, `y`.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn copysign(x: f64, y: f64) -> f64 {
|
||||
super::generic::copysign(x, y)
|
||||
}
|
||||
|
|
@ -31,7 +31,7 @@ pub fn copysign(x: f64, y: f64) -> f64 {
|
|||
/// Constructs a number with the magnitude (absolute value) of its
|
||||
/// first argument, `x`, and the sign of its second argument, `y`.
|
||||
#[cfg(f128_enabled)]
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn copysignf128(x: f128, y: f128) -> f128 {
|
||||
super::generic::copysign(x, y)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ use super::{k_cos, k_sin, rem_pio2};
|
|||
/// The cosine of `x` (f64).
|
||||
///
|
||||
/// `x` is specified in radians.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn cos(x: f64) -> f64 {
|
||||
let ix = (f64::to_bits(x) >> 32) as u32 & 0x7fffffff;
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ const C4_PIO2: f64 = 4. * FRAC_PI_2; /* 0x401921FB, 0x54442D18 */
|
|||
/// The cosine of `x` (f32).
|
||||
///
|
||||
/// `x` is specified in radians.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn cosf(x: f32) -> f32 {
|
||||
let x64 = x as f64;
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use super::{exp, expm1, k_expo2};
|
|||
/// Computes the hyperbolic cosine of the argument x.
|
||||
/// Is defined as `(exp(x) + exp(-x))/2`
|
||||
/// Angles are specified in radians.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn cosh(mut x: f64) -> f64 {
|
||||
/* |x| */
|
||||
let mut ix = x.to_bits();
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use super::{expf, expm1f, k_expo2f};
|
|||
/// Computes the hyperbolic cosine of the argument x.
|
||||
/// Is defined as `(exp(x) + exp(-x))/2`
|
||||
/// Angles are specified in radians.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn coshf(mut x: f32) -> f32 {
|
||||
let x1p120 = f32::from_bits(0x7b800000); // 0x1p120f === 2 ^ 120
|
||||
|
||||
|
|
|
|||
|
|
@ -219,7 +219,7 @@ fn erfc2(ix: u32, mut x: f64) -> f64 {
|
|||
/// Calculates an approximation to the “error function”, which estimates
|
||||
/// the probability that an observation will fall within x standard
|
||||
/// deviations of the mean (assuming a normal distribution).
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn erf(x: f64) -> f64 {
|
||||
let r: f64;
|
||||
let s: f64;
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ fn erfc2(mut ix: u32, mut x: f32) -> f32 {
|
|||
/// Calculates an approximation to the “error function”, which estimates
|
||||
/// the probability that an observation will fall within x standard
|
||||
/// deviations of the mean (assuming a normal distribution).
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn erff(x: f32) -> f32 {
|
||||
let r: f32;
|
||||
let s: f32;
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ const P5: f64 = 4.13813679705723846039e-08; /* 0x3E663769, 0x72BEA4D0 */
|
|||
///
|
||||
/// Calculate the exponential of `x`, that is, *e* raised to the power `x`
|
||||
/// (where *e* is the base of the natural system of logarithms, approximately 2.71828).
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn exp(mut x: f64) -> f64 {
|
||||
let x1p1023 = f64::from_bits(0x7fe0000000000000); // 0x1p1023 === 2 ^ 1023
|
||||
let x1p_149 = f64::from_bits(0x36a0000000000000); // 0x1p-149 === 2 ^ -149
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ const P10: &[f64] = &[
|
|||
];
|
||||
|
||||
/// Calculates 10 raised to the power of `x` (f64).
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn exp10(x: f64) -> f64 {
|
||||
let (mut y, n) = modf(x);
|
||||
let u: u64 = n.to_bits();
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ const P10: &[f32] = &[
|
|||
];
|
||||
|
||||
/// Calculates 10 raised to the power of `x` (f32).
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn exp10f(x: f32) -> f32 {
|
||||
let (mut y, n) = modff(x);
|
||||
let u = n.to_bits();
|
||||
|
|
|
|||
|
|
@ -322,7 +322,7 @@ static TBL: [u64; TBLSIZE * 2] = [
|
|||
/// Exponential, base 2 (f64)
|
||||
///
|
||||
/// Calculate `2^x`, that is, 2 raised to the power `x`.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn exp2(mut x: f64) -> f64 {
|
||||
let redux = f64::from_bits(0x4338000000000000) / TBLSIZE as f64;
|
||||
let p1 = f64::from_bits(0x3fe62e42fefa39ef);
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ static EXP2FT: [u64; TBLSIZE] = [
|
|||
/// Exponential, base 2 (f32)
|
||||
///
|
||||
/// Calculate `2^x`, that is, 2 raised to the power `x`.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn exp2f(mut x: f32) -> f32 {
|
||||
let redux = f32::from_bits(0x4b400000) / TBLSIZE as f32;
|
||||
let p1 = f32::from_bits(0x3f317218);
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ const P2: f32 = -2.7667332906e-3; /* -0xb55215.0p-32 */
|
|||
///
|
||||
/// Calculate the exponential of `x`, that is, *e* raised to the power `x`
|
||||
/// (where *e* is the base of the natural system of logarithms, approximately 2.71828).
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn expf(mut x: f32) -> f32 {
|
||||
let x1p127 = f32::from_bits(0x7f000000); // 0x1p127f === 2 ^ 127
|
||||
let x1p_126 = f32::from_bits(0x800000); // 0x1p-126f === 2 ^ -126 /*original 0x1p-149f ??????????? */
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ const Q5: f64 = -2.01099218183624371326e-07; /* BE8AFDB7 6E09C32D */
|
|||
/// system of logarithms, approximately 2.71828).
|
||||
/// The result is accurate even for small values of `x`,
|
||||
/// where using `exp(x)-1` would lose many significant digits.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn expm1(mut x: f64) -> f64 {
|
||||
let hi: f64;
|
||||
let lo: f64;
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ const Q2: f32 = 1.5807170421e-3; /* 0xcf3010.0p-33 */
|
|||
/// system of logarithms, approximately 2.71828).
|
||||
/// The result is accurate even for small values of `x`,
|
||||
/// where using `exp(x)-1` would lose many significant digits.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn expm1f(mut x: f32) -> f32 {
|
||||
let x1p127 = f32::from_bits(0x7f000000); // 0x1p127f === 2 ^ 127
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use super::{combine_words, exp};
|
||||
|
||||
/* exp(x)/2 for x >= log(DBL_MAX), slightly better than 0.5*exp(x/2)*exp(x/2) */
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub(crate) fn expo2(x: f64) -> f64 {
|
||||
/* k is such that k*ln2 has minimal relative error and x - kln2 > log(DBL_MIN) */
|
||||
const K: i32 = 2043;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
/// Calculates the absolute value (magnitude) of the argument `x`,
|
||||
/// by direct manipulation of the bit representation of `x`.
|
||||
#[cfg(f16_enabled)]
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fabsf16(x: f16) -> f16 {
|
||||
super::generic::fabs(x)
|
||||
}
|
||||
|
|
@ -12,7 +12,7 @@ pub fn fabsf16(x: f16) -> f16 {
|
|||
///
|
||||
/// Calculates the absolute value (magnitude) of the argument `x`,
|
||||
/// by direct manipulation of the bit representation of `x`.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fabsf(x: f32) -> f32 {
|
||||
select_implementation! {
|
||||
name: fabsf,
|
||||
|
|
@ -27,7 +27,7 @@ pub fn fabsf(x: f32) -> f32 {
|
|||
///
|
||||
/// Calculates the absolute value (magnitude) of the argument `x`,
|
||||
/// by direct manipulation of the bit representation of `x`.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fabs(x: f64) -> f64 {
|
||||
select_implementation! {
|
||||
name: fabs,
|
||||
|
|
@ -43,7 +43,7 @@ pub fn fabs(x: f64) -> f64 {
|
|||
/// Calculates the absolute value (magnitude) of the argument `x`,
|
||||
/// by direct manipulation of the bit representation of `x`.
|
||||
#[cfg(f128_enabled)]
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fabsf128(x: f128) -> f128 {
|
||||
super::generic::fabs(x)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
///
|
||||
/// A range error may occur.
|
||||
#[cfg(f16_enabled)]
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fdimf16(x: f16, y: f16) -> f16 {
|
||||
super::generic::fdim(x, y)
|
||||
}
|
||||
|
|
@ -20,7 +20,7 @@ pub fn fdimf16(x: f16, y: f16) -> f16 {
|
|||
/// * NAN if either argument is NAN.
|
||||
///
|
||||
/// A range error may occur.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fdimf(x: f32, y: f32) -> f32 {
|
||||
super::generic::fdim(x, y)
|
||||
}
|
||||
|
|
@ -33,7 +33,7 @@ pub fn fdimf(x: f32, y: f32) -> f32 {
|
|||
/// * NAN if either argument is NAN.
|
||||
///
|
||||
/// A range error may occur.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fdim(x: f64, y: f64) -> f64 {
|
||||
super::generic::fdim(x, y)
|
||||
}
|
||||
|
|
@ -47,7 +47,7 @@ pub fn fdim(x: f64, y: f64) -> f64 {
|
|||
///
|
||||
/// A range error may occur.
|
||||
#[cfg(f128_enabled)]
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fdimf128(x: f128, y: f128) -> f128 {
|
||||
super::generic::fdim(x, y)
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue