use std::{fmt, iter};

use arrayvec::ArrayVec;
use rustc_abi::{
    AddressSpace, Align, BackendRepr, CanonAbi, ExternAbi, FieldsShape, HasDataLayout, Primitive,
    Reg, RegKind, Scalar, Size, TyAbiInterface, TyAndLayout, Variants,
};
use rustc_macros::StableHash;

pub use crate::spec::AbiMap;
use crate::spec::{Arch, HasTargetSpec, HasX86AbiOpt};

mod aarch64;
mod amdgpu;
mod arm;
mod avr;
mod bpf;
mod csky;
mod hexagon;
mod loongarch;
mod m68k;
mod mips;
mod mips64;
mod msp430;
mod nvptx64;
mod powerpc;
mod powerpc64;
mod riscv;
mod s390x;
mod sparc;
mod sparc64;
mod wasm;
mod x86;
mod x86_64;
mod x86_win32;
mod x86_win64;
mod xtensa;

#[derive(Clone, PartialEq, Eq, Hash, Debug, StableHash)]
pub enum PassMode {
    /// Ignore the argument.
    ///
    /// The argument is a ZST.
    Ignore,
    /// Pass the argument directly.
    ///
    /// The argument has a layout abi of `Scalar` or `Vector`.
    /// Unfortunately due to past mistakes, in rare cases on wasm, it can also be `Aggregate`.
    /// This is bad since it leaks LLVM implementation details into the ABI.
    /// (Also see <https://github.com/rust-lang/rust/issues/115666>.)
    Direct(ArgAttributes),
    /// Pass a pair's elements directly in two arguments.
    ///
    /// The argument has a layout abi of `ScalarPair`.
    Pair(ArgAttributes, ArgAttributes),
    /// Pass the argument after casting it. See the `CastTarget` docs for details.
    ///
    /// `pad_i32` indicates if a `Reg::i32()` dummy argument is emitted before the real argument.
    Cast { pad_i32: bool, cast: Box<CastTarget> },
    /// Pass the argument indirectly via a hidden pointer.
    ///
    /// The `meta_attrs` value, if any, is for the metadata (vtable or length) of an unsized
    /// argument. (This is the only mode that supports unsized arguments.)
    ///
    /// `on_stack` defines that the value should be passed at a fixed stack offset in accordance to
    /// the ABI rather than passed using a pointer. This corresponds to the `byval` LLVM argument
    /// attribute. The `byval` argument will use a byte array with the same size as the Rust type
    /// (which ensures that padding is preserved and that we do not rely on LLVM's struct layout),
    /// and will use the alignment specified in `attrs.pointee_align` (if `Some`) or the type's
    /// alignment (if `None`). This means that the alignment will not always
    /// match the Rust type's alignment; see documentation of `pass_by_stack_offset` for more info.
    ///
    /// `on_stack` cannot be true for unsized arguments, i.e., when `meta_attrs` is `Some`.
    Indirect { attrs: ArgAttributes, meta_attrs: Option<ArgAttributes>, on_stack: bool },
}

impl PassMode {
    /// Checks if these two `PassMode` are equal enough to be considered "the same for all
    /// function call ABIs". However, the `Layout` can also impact ABI decisions,
    /// so that needs to be compared as well!
    pub fn eq_abi(&self, other: &Self) -> bool {
        match (self, other) {
            (PassMode::Ignore, PassMode::Ignore) => true,
            (PassMode::Direct(a1), PassMode::Direct(a2)) => a1.eq_abi(a2),
            (PassMode::Pair(a1, b1), PassMode::Pair(a2, b2)) => a1.eq_abi(a2) && b1.eq_abi(b2),
            (
                PassMode::Cast { cast: c1, pad_i32: pad1 },
                PassMode::Cast { cast: c2, pad_i32: pad2 },
            ) => c1.eq_abi(c2) && pad1 == pad2,
            (
                PassMode::Indirect { attrs: a1, meta_attrs: None, on_stack: s1 },
                PassMode::Indirect { attrs: a2, meta_attrs: None, on_stack: s2 },
            ) => a1.eq_abi(a2) && s1 == s2,
            (
                PassMode::Indirect { attrs: a1, meta_attrs: Some(e1), on_stack: s1 },
                PassMode::Indirect { attrs: a2, meta_attrs: Some(e2), on_stack: s2 },
            ) => a1.eq_abi(a2) && e1.eq_abi(e2) && s1 == s2,
            _ => false,
        }
    }
}

// Hack to disable non_upper_case_globals only for the bitflags! and not for the rest
// of this module
pub use attr_impl::ArgAttribute;

#[allow(non_upper_case_globals)]
#[allow(unused)]
mod attr_impl {
    use rustc_macros::StableHash;

    // The subset of llvm::Attribute needed for arguments, packed into a bitfield.
    #[derive(Clone, Copy, Default, Hash, PartialEq, Eq, StableHash)]
    pub struct ArgAttribute(u16);
    bitflags::bitflags! {
        impl ArgAttribute: u16 {
            const CapturesNone     = 0b111;
            const CapturesAddress  = 0b110;
            const CapturesReadOnly = 0b100;
            const NoAlias  = 1 << 3;
            const NonNull  = 1 << 4;
            const ReadOnly = 1 << 5;
            const InReg    = 1 << 6;
            const NoUndef  = 1 << 7;
            const Writable = 1 << 8;
            /// It is UB for this pointer or any pointer derived from it to be used for
            /// deallocation (except for zero-sized deallocation) while the function is
            /// executing. Only valid on arguments (including return values that are passed
            /// indirectly as arguments).
            const NoFree   = 1 << 9;
        }
    }
    rustc_data_structures::external_bitflags_debug! { ArgAttribute }
}

/// Sometimes an ABI requires small integers to be extended to a full or partial register. This enum
/// defines if this extension should be zero-extension or sign-extension when necessary. When it is
/// not necessary to extend the argument, this enum is ignored.
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, StableHash)]
pub enum ArgExtension {
    None,
    Zext,
    Sext,
}

/// A compact representation of LLVM attributes (at least those relevant for this module)
/// that can be manipulated without interacting with LLVM's Attribute machinery.
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, StableHash)]
pub struct ArgAttributes {
    pub regular: ArgAttribute,
    pub arg_ext: ArgExtension,
    /// If the pointer is not null, the minimum dereferenceable size of the pointee, at the time of
    /// function entry (for arguments) or function return (for return values).
    pub pointee_size: Size,
    /// The minimum alignment of the pointee, if any.
    pub pointee_align: Option<Align>,
}

impl ArgAttributes {
    pub fn new() -> Self {
        ArgAttributes {
            regular: ArgAttribute::default(),
            arg_ext: ArgExtension::None,
            pointee_size: Size::ZERO,
            pointee_align: None,
        }
    }

    pub fn ext(&mut self, ext: ArgExtension) -> &mut Self {
        assert!(
            self.arg_ext == ArgExtension::None || self.arg_ext == ext,
            "cannot set {:?} when {:?} is already set",
            ext,
            self.arg_ext
        );
        self.arg_ext = ext;
        self
    }

    pub fn set(&mut self, attr: ArgAttribute) -> &mut Self {
        self.regular |= attr;
        self
    }

    pub fn contains(&self, attr: ArgAttribute) -> bool {
        self.regular.contains(attr)
    }

    /// Checks if these two `ArgAttributes` are equal enough to be considered "the same for all
    /// function call ABIs".
    pub fn eq_abi(&self, other: &Self) -> bool {
        // There's only one regular attribute that matters for the call ABI: InReg.
        // Everything else is things like noalias, dereferenceable, nonnull, ...
        // (This also applies to pointee_size, pointee_align.)
        if self.regular.contains(ArgAttribute::InReg) != other.regular.contains(ArgAttribute::InReg)
        {
            return false;
        }
        // We also compare the sign extension mode -- this could let the callee make assumptions
        // about bits that conceptually were not even passed.
        if self.arg_ext != other.arg_ext {
            return false;
        }
        true
    }
}

impl From<ArgAttribute> for ArgAttributes {
    fn from(value: ArgAttribute) -> Self {
        Self {
            regular: value,
            arg_ext: ArgExtension::None,
            pointee_size: Size::ZERO,
            pointee_align: None,
        }
    }
}

/// An argument passed entirely registers with the
/// same kind (e.g., HFA / HVA on PPC64 and AArch64).
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, StableHash)]
pub struct Uniform {
    pub unit: Reg,

    /// The total size of the argument, which can be:
    /// * equal to `unit.size` (one scalar/vector),
    /// * a multiple of `unit.size` (an array of scalar/vectors),
    /// * if `unit.kind` is `Integer`, the last element can be shorter, i.e., `{ i64, i64, i32 }`
    ///   for 64-bit integers with a total size of 20 bytes. When the argument is actually passed,
    ///   this size will be rounded up to the nearest multiple of `unit.size`.
    pub total: Size,

    /// Indicate that the argument is consecutive, in the sense that either all values need to be
    /// passed in register, or all on the stack. If they are passed on the stack, there should be
    /// no additional padding between elements.
    pub is_consecutive: bool,
}

impl From<Reg> for Uniform {
    fn from(unit: Reg) -> Uniform {
        Uniform { unit, total: unit.size, is_consecutive: false }
    }
}

impl Uniform {
    pub fn align<C: HasDataLayout>(&self, cx: &C) -> Align {
        self.unit.align(cx)
    }

    /// Pass using one or more values of the given type, without requiring them to be consecutive.
    /// That is, some values may be passed in register and some on the stack.
    pub fn new(unit: Reg, total: Size) -> Self {
        Uniform { unit, total, is_consecutive: false }
    }

    /// Pass using one or more consecutive values of the given type. Either all values will be
    /// passed in registers, or all on the stack.
    pub fn consecutive(unit: Reg, total: Size) -> Self {
        Uniform { unit, total, is_consecutive: true }
    }
}

/// Describes the type used for `PassMode::Cast`.
///
/// Passing arguments in this mode works as follows: the registers in the `prefix` (the ones that
/// are `Some`) get laid out one after the other (using `repr(C)` layout rules). Then the
/// `rest.unit` register type gets repeated often enough to cover `rest.size`. This describes the
/// actual type used for the call; the Rust type of the argument is then transmuted to this ABI type
/// (and all data in the padding between the registers is dropped).
#[derive(Clone, PartialEq, Eq, Hash, Debug, StableHash)]
pub struct CastTarget {
    // Note that this is fixed to 8 elements for now as ABIs currently don't
    // need anything further beyond that, and when this code was originally
    // refactored to use `ArrayVec` it was already using 8, so that stuck
    // around.
    pub prefix: ArrayVec<Reg, 8>,
    /// The offset of `rest` from the start of the value. Currently only implemented for a `Reg`
    /// pair created by the `offset_pair` method.
    pub rest_offset: Option<Size>,
    pub rest: Uniform,
    pub attrs: ArgAttributes,
}

impl From<Reg> for CastTarget {
    fn from(unit: Reg) -> CastTarget {
        CastTarget::from(Uniform::from(unit))
    }
}

impl From<Uniform> for CastTarget {
    fn from(uniform: Uniform) -> CastTarget {
        Self::prefixed(Default::default(), uniform)
    }
}

impl CastTarget {
    pub fn prefixed(prefix: ArrayVec<Reg, 8>, rest: Uniform) -> Self {
        Self { prefix, rest_offset: None, rest, attrs: ArgAttributes::new() }
    }

    pub fn offset_pair(a: Reg, offset_from_start: Size, b: Reg) -> Self {
        let mut prefix = ArrayVec::new();
        prefix.push(a);
        Self {
            prefix,
            rest_offset: Some(offset_from_start),
            rest: b.into(),
            attrs: ArgAttributes::new(),
        }
    }

    pub fn with_attrs(mut self, attrs: ArgAttributes) -> Self {
        self.attrs = attrs;
        self
    }

    pub fn pair(a: Reg, b: Reg) -> CastTarget {
        let mut prefix = ArrayVec::new();
        prefix.push(a);
        Self::prefixed(prefix, Uniform::from(b))
    }

    /// When you only access the range containing valid data, you can use this unaligned size;
    /// otherwise, use the safer `size` method.
    pub fn unaligned_size<C: HasDataLayout>(&self, _cx: &C) -> Size {
        // Prefix arguments are passed in specific designated registers
        let prefix_size = if let Some(offset_from_start) = self.rest_offset {
            offset_from_start
        } else {
            self.prefix.iter().map(|reg| reg.size).fold(Size::ZERO, |acc, size| acc + size)
        };
        // Remaining arguments are passed in chunks of the unit size
        let rest_size =
            self.rest.unit.size * self.rest.total.bytes().div_ceil(self.rest.unit.size.bytes());

        prefix_size + rest_size
    }

    pub fn size<C: HasDataLayout>(&self, cx: &C) -> Size {
        self.unaligned_size(cx).align_to(self.align(cx))
    }

    pub fn align<C: HasDataLayout>(&self, cx: &C) -> Align {
        self.prefix
            .iter()
            .map(|reg| reg.align(cx))
            .fold(cx.data_layout().aggregate_align.max(self.rest.align(cx)), |acc, align| {
                acc.max(align)
            })
    }

    /// Checks if these two `CastTarget` are equal enough to be considered "the same for all
    /// function call ABIs".
    pub fn eq_abi(&self, other: &Self) -> bool {
        let CastTarget {
            prefix: prefix_l,
            rest_offset: rest_offset_l,
            rest: rest_l,
            attrs: attrs_l,
        } = self;
        let CastTarget {
            prefix: prefix_r,
            rest_offset: rest_offset_r,
            rest: rest_r,
            attrs: attrs_r,
        } = other;
        prefix_l == prefix_r
            && rest_offset_l == rest_offset_r
            && rest_l == rest_r
            && attrs_l.eq_abi(attrs_r)
    }
}

/// Information about how to pass an argument to,
/// or return a value from, a function, under some ABI.
#[derive(Clone, PartialEq, Eq, Hash, StableHash)]
pub struct ArgAbi<'a, Ty> {
    pub layout: TyAndLayout<'a, Ty>,
    pub mode: PassMode,
}

// Needs to be a custom impl because of the bounds on the `TyAndLayout` debug impl.
impl<'a, Ty: fmt::Display> fmt::Debug for ArgAbi<'a, Ty> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let ArgAbi { layout, mode } = self;
        f.debug_struct("ArgAbi").field("layout", layout).field("mode", mode).finish()
    }
}

impl<'a, Ty> ArgAbi<'a, Ty> {
    /// This defines the "default ABI" for that type, that is then later adjusted in `fn_abi_adjust_for_abi`.
    pub fn new(
        cx: &impl HasDataLayout,
        layout: TyAndLayout<'a, Ty>,
        scalar_attrs: impl Fn(Scalar, Size) -> ArgAttributes,
    ) -> Self {
        let mode = match layout.backend_repr {
            _ if layout.is_zst() => PassMode::Ignore,
            BackendRepr::Scalar(scalar) => PassMode::Direct(scalar_attrs(scalar, Size::ZERO)),
            BackendRepr::ScalarPair(a, b) => PassMode::Pair(
                scalar_attrs(a, Size::ZERO),
                scalar_attrs(b, a.size(cx).align_to(b.align(cx).abi)),
            ),
            BackendRepr::SimdVector { .. } => PassMode::Direct(ArgAttributes::new()),
            BackendRepr::Memory { .. } => Self::indirect_pass_mode(&layout),
            BackendRepr::SimdScalableVector { .. } => PassMode::Direct(ArgAttributes::new()),
        };
        ArgAbi { layout, mode }
    }

    fn indirect_pass_mode(layout: &TyAndLayout<'a, Ty>) -> PassMode {
        let mut attrs = ArgAttributes::new();

        // For non-immediate arguments the callee gets its own copy of
        // the value on the stack, so there are no aliases. The function
        // can capture the address of the argument, but not the provenance.
        attrs
            .set(ArgAttribute::NoAlias)
            .set(ArgAttribute::CapturesAddress)
            .set(ArgAttribute::NonNull)
            .set(ArgAttribute::NoUndef)
            .set(ArgAttribute::NoFree);
        attrs.pointee_size = layout.size;
        attrs.pointee_align = Some(layout.align.abi);

        let meta_attrs = layout.is_unsized().then_some(ArgAttributes::new());

        PassMode::Indirect { attrs, meta_attrs, on_stack: false }
    }

    /// Pass this argument directly instead. Should NOT be used!
    /// Only exists because of past ABI mistakes that will take time to fix
    /// (see <https://github.com/rust-lang/rust/issues/115666>).
    #[track_caller]
    pub fn make_direct_deprecated(&mut self) {
        match self.mode {
            PassMode::Indirect { .. } => {
                self.mode = PassMode::Direct(ArgAttributes::new());
            }
            PassMode::Ignore | PassMode::Direct(_) | PassMode::Pair(_, _) => {} // already direct
            _ => panic!("Tried to make {:?} direct", self.mode),
        }
    }

    /// Pass this argument indirectly, by passing a (thin or wide) pointer to the argument instead.
    /// This is valid for both sized and unsized arguments.
    #[track_caller]
    pub fn make_indirect(&mut self) {
        match self.mode {
            PassMode::Direct(_) | PassMode::Pair(_, _) => {
                self.mode = Self::indirect_pass_mode(&self.layout);
            }
            PassMode::Indirect { attrs: _, meta_attrs: _, on_stack: false } => {
                // already indirect
            }
            _ => panic!("Tried to make {:?} indirect", self.mode),
        }
    }

    /// Same as `make_indirect`, but for arguments that are ignored. Only needed for ABIs that pass
    /// ZSTs indirectly.
    #[track_caller]
    pub fn make_indirect_from_ignore(&mut self) {
        match self.mode {
            PassMode::Ignore => {
                self.mode = Self::indirect_pass_mode(&self.layout);
            }
            PassMode::Indirect { attrs: _, meta_attrs: _, on_stack: false } => {
                // already indirect
            }
            _ => panic!("Tried to make {:?} indirect (expected `PassMode::Ignore`)", self.mode),
        }
    }

    /// Pass this argument indirectly, by placing it at a fixed stack offset.
    /// This corresponds to the `byval` LLVM argument attribute.
    /// This is only valid for sized arguments.
    ///
    /// `byval_align` specifies the alignment of the `byval` stack slot, which does not need to
    /// correspond to the type's alignment. This will be `Some` if the target's ABI specifies that
    /// stack slots used for arguments passed by-value have specific alignment requirements which
    /// differ from the alignment used in other situations.
    ///
    /// If `None`, the type's alignment is used.
    ///
    /// If the resulting alignment differs from the type's alignment,
    /// the argument will be copied to an alloca with sufficient alignment,
    /// either in the caller (if the type's alignment is lower than the byval alignment)
    /// or in the callee (if the type's alignment is higher than the byval alignment),
    /// to ensure that Rust code never sees an underaligned pointer.
    pub fn pass_by_stack_offset(&mut self, byval_align: Option<Align>) {
        assert!(!self.layout.is_unsized(), "used byval ABI for unsized layout");
        self.make_indirect();
        match self.mode {
            PassMode::Indirect { ref mut attrs, meta_attrs: _, ref mut on_stack } => {
                *on_stack = true;

                // Some platforms, like 32-bit x86, change the alignment of the type when passing
                // `byval`. Account for that.
                if let Some(byval_align) = byval_align {
                    // On all targets with byval align this is currently true, so let's assert it.
                    debug_assert!(byval_align >= Align::from_bytes(4).unwrap());
                    attrs.pointee_align = Some(byval_align);
                }
            }
            _ => unreachable!(),
        }
    }

    pub fn extend_integer_width_to(&mut self, bits: u64) {
        // Only integers have signedness
        if let BackendRepr::Scalar(scalar) = self.layout.backend_repr
            && let Primitive::Int(i, signed) = scalar.primitive()
            && i.size().bits() < bits
            && let PassMode::Direct(ref mut attrs) = self.mode
        {
            if signed {
                attrs.ext(ArgExtension::Sext)
            } else {
                attrs.ext(ArgExtension::Zext)
            };
        }
    }

    pub fn cast_to<T: Into<CastTarget>>(&mut self, target: T) {
        self.mode = PassMode::Cast { cast: Box::new(target.into()), pad_i32: false };
    }

    pub fn cast_to_with_attrs<T: Into<CastTarget>>(&mut self, target: T, attrs: ArgAttributes) {
        self.mode =
            PassMode::Cast { cast: Box::new(target.into().with_attrs(attrs)), pad_i32: false };
    }

    pub fn cast_to_and_pad_i32<T: Into<CastTarget>>(&mut self, target: T, pad_i32: bool) {
        self.mode = PassMode::Cast { cast: Box::new(target.into()), pad_i32 };
    }

    pub fn is_indirect(&self) -> bool {
        matches!(self.mode, PassMode::Indirect { .. })
    }

    pub fn is_sized_indirect(&self) -> bool {
        matches!(self.mode, PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: _ })
    }

    pub fn is_unsized_indirect(&self) -> bool {
        matches!(self.mode, PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ })
    }

    pub fn is_ignore(&self) -> bool {
        matches!(self.mode, PassMode::Ignore)
    }

    /// Checks if these two `ArgAbi` are equal enough to be considered "the same for all
    /// function call ABIs".
    pub fn eq_abi(&self, other: &Self) -> bool
    where
        Ty: PartialEq,
    {
        // Ideally we'd just compare the `mode`, but that is not enough -- for some modes LLVM will look
        // at the type.
        self.layout.eq_abi(&other.layout) && self.mode.eq_abi(&other.mode) && {
            // `fn_arg_sanity_check` accepts `PassMode::Direct` for some aggregates.
            // That elevates any type difference to an ABI difference since we just use the
            // full Rust type as the LLVM argument/return type.
            if matches!(self.mode, PassMode::Direct(..))
                && matches!(self.layout.backend_repr, BackendRepr::Memory { .. })
            {
                // For aggregates in `Direct` mode to be compatible, the types need to be equal.
                self.layout.ty == other.layout.ty
            } else {
                true
            }
        }
    }
}

#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, StableHash)]
pub enum RiscvInterruptKind {
    Machine,
    Supervisor,
}

impl RiscvInterruptKind {
    pub fn as_str(&self) -> &'static str {
        match self {
            Self::Machine => "machine",
            Self::Supervisor => "supervisor",
        }
    }
}

/// Metadata describing how the arguments to a native function
/// should be passed in order to respect the native ABI.
///
/// The signature represented by this type may not match the MIR function signature.
/// Certain attributes, like `#[track_caller]` can introduce additional arguments, which are present in [`FnAbi`], but not in `FnSig`.
/// The std::offload module also adds an addition dyn_ptr argument to the GpuKernel ABI.
/// While this difference is rarely relevant, it should still be kept in mind.
///
/// I will do my best to describe this structure, but these
/// comments are reverse-engineered and may be inaccurate. -NDM
#[derive(Clone, PartialEq, Eq, Hash, StableHash)]
pub struct FnAbi<'a, Ty> {
    /// The type, layout, and information about how each argument is passed.
    pub args: Box<[ArgAbi<'a, Ty>]>,

    /// The layout, type, and the way a value is returned from this function.
    pub ret: ArgAbi<'a, Ty>,

    /// Marks this function as variadic (accepting a variable number of arguments).
    pub c_variadic: bool,

    /// The count of non-variadic arguments.
    ///
    /// Should only be different from args.len() when c_variadic is true.
    /// This can be used to know whether an argument is variadic or not.
    pub fixed_count: u32,
    /// The calling convention of this function.
    pub conv: CanonAbi,
    /// Indicates if an unwind may happen across a call to this function.
    pub can_unwind: bool,
}

// Needs to be a custom impl because of the bounds on the `TyAndLayout` debug impl.
impl<'a, Ty: fmt::Display> fmt::Debug for FnAbi<'a, Ty> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let FnAbi { args, ret, c_variadic, fixed_count, conv, can_unwind } = self;
        f.debug_struct("FnAbi")
            .field("args", args)
            .field("ret", ret)
            .field("c_variadic", c_variadic)
            .field("fixed_count", fixed_count)
            .field("conv", conv)
            .field("can_unwind", can_unwind)
            .finish()
    }
}

impl<'a, Ty> FnAbi<'a, Ty> {
    pub fn adjust_for_foreign_abi<C>(&mut self, cx: &C, abi: ExternAbi)
    where
        Ty: TyAbiInterface<'a, C> + Copy,
        C: HasDataLayout + HasTargetSpec + HasX86AbiOpt,
    {
        if abi == ExternAbi::X86Interrupt {
            if let Some(arg) = self.args.first_mut() {
                arg.pass_by_stack_offset(None);
            }
            return;
        }

        let spec = cx.target_spec();
        match &spec.arch {
            Arch::X86 => {
                let (flavor, regparm) = match abi {
                    ExternAbi::Fastcall { .. } | ExternAbi::Vectorcall { .. } => {
                        (x86::Flavor::FastcallOrVectorcall, None)
                    }
                    ExternAbi::C { .. } | ExternAbi::Cdecl { .. } | ExternAbi::Stdcall { .. } => {
                        (x86::Flavor::General, cx.x86_abi_opt().regparm)
                    }
                    _ => (x86::Flavor::General, None),
                };
                let reg_struct_return = cx.x86_abi_opt().reg_struct_return;
                let opts = x86::X86Options { flavor, regparm, reg_struct_return };
                if spec.is_like_msvc {
                    x86_win32::compute_abi_info(cx, self, opts);
                } else {
                    x86::compute_abi_info(cx, self, opts);
                }
            }
            Arch::X86_64 => match abi {
                ExternAbi::SysV64 { .. } => x86_64::compute_abi_info(cx, self),
                ExternAbi::Win64 { .. } | ExternAbi::Vectorcall { .. } => {
                    x86_win64::compute_abi_info(cx, self)
                }
                _ => {
                    if cx.target_spec().is_like_windows {
                        x86_win64::compute_abi_info(cx, self)
                    } else {
                        x86_64::compute_abi_info(cx, self)
                    }
                }
            },
            Arch::AArch64 | Arch::Arm64EC => {
                let kind = if cx.target_spec().is_like_darwin {
                    aarch64::AbiKind::DarwinPCS
                } else if cx.target_spec().is_like_windows {
                    aarch64::AbiKind::Win64
                } else {
                    aarch64::AbiKind::AAPCS
                };
                aarch64::compute_abi_info(cx, self, kind)
            }
            Arch::AmdGpu => amdgpu::compute_abi_info(cx, self),
            Arch::Arm => arm::compute_abi_info(cx, self),
            Arch::Avr => avr::compute_abi_info(cx, self),
            Arch::LoongArch32 | Arch::LoongArch64 => loongarch::compute_abi_info(cx, self),
            Arch::M68k => m68k::compute_abi_info(cx, self),
            Arch::CSky => csky::compute_abi_info(cx, self),
            Arch::Mips | Arch::Mips32r6 => mips::compute_abi_info(cx, self),
            Arch::Mips64 | Arch::Mips64r6 => mips64::compute_abi_info(cx, self),
            Arch::PowerPC => powerpc::compute_abi_info(cx, self),
            Arch::PowerPC64 => powerpc64::compute_abi_info(cx, self),
            Arch::S390x => s390x::compute_abi_info(cx, self),
            Arch::Msp430 => msp430::compute_abi_info(cx, self),
            Arch::Sparc => sparc::compute_abi_info(cx, self),
            Arch::Sparc64 => sparc64::compute_abi_info(cx, self),
            Arch::Nvptx64 => {
                if abi == ExternAbi::PtxKernel || abi == ExternAbi::GpuKernel {
                    nvptx64::compute_ptx_kernel_abi_info(cx, self)
                } else {
                    nvptx64::compute_abi_info(cx, self)
                }
            }
            Arch::Hexagon => hexagon::compute_abi_info(cx, self),
            Arch::Xtensa => xtensa::compute_abi_info(cx, self),
            Arch::RiscV32 | Arch::RiscV64 => riscv::compute_abi_info(cx, self),
            Arch::Wasm32 | Arch::Wasm64 => wasm::compute_abi_info(cx, self),
            Arch::Bpf => bpf::compute_abi_info(cx, self),
            arch @ (Arch::SpirV | Arch::Other(_)) => {
                panic!("no lowering implemented for {arch}")
            }
        }
    }

    pub fn adjust_for_rust_abi<C>(&mut self, cx: &C)
    where
        Ty: TyAbiInterface<'a, C> + Copy,
        C: HasDataLayout + HasTargetSpec,
    {
        let spec = cx.target_spec();
        match &spec.arch {
            Arch::X86 => x86::compute_rust_abi_info(cx, self),
            Arch::RiscV32 | Arch::RiscV64 => riscv::compute_rust_abi_info(cx, self),
            Arch::LoongArch32 | Arch::LoongArch64 => loongarch::compute_rust_abi_info(cx, self),
            Arch::AArch64 => aarch64::compute_rust_abi_info(cx, self),
            Arch::Bpf => bpf::compute_rust_abi_info(self),
            _ => {}
        };

        for (arg_idx, arg) in self
            .args
            .iter_mut()
            .enumerate()
            .map(|(idx, arg)| (Some(idx), arg))
            .chain(iter::once((None, &mut self.ret)))
        {
            // If the logic above already picked a specific type to cast the argument to, leave that
            // in place.
            if matches!(arg.mode, PassMode::Ignore | PassMode::Cast { .. }) {
                continue;
            }

            if arg_idx.is_none()
                && arg.layout.size > Primitive::Pointer(AddressSpace::ZERO).size(cx) * 2
                && !matches!(
                    arg.layout.backend_repr,
                    BackendRepr::SimdVector { .. } | BackendRepr::SimdScalableVector { .. }
                )
            {
                // Return values larger than 2 registers using a return area
                // pointer. LLVM and Cranelift disagree about how to return
                // values that don't fit in the registers designated for return
                // values. LLVM will force the entire return value to be passed
                // by return area pointer, while Cranelift will look at each IR level
                // return value independently and decide to pass it in a
                // register or not, which would result in the return value
                // being passed partially in registers and partially through a
                // return area pointer. For large IR-level values such as `i128`,
                // cranelift will even split up the value into smaller chunks.
                //
                // While Cranelift may need to be fixed as the LLVM behavior is
                // generally more correct with respect to the surface language,
                // forcing this behavior in rustc itself makes it easier for
                // other backends to conform to the Rust ABI and for the C ABI
                // rustc already handles this behavior anyway.
                //
                // In addition LLVM's decision to pass the return value in
                // registers or using a return area pointer depends on how
                // exactly the return type is lowered to an LLVM IR type. For
                // example `Option<u128>` can be lowered as `{ i128, i128 }`
                // in which case the x86_64 backend would use a return area
                // pointer, or it could be passed as `{ i32, i128 }` in which
                // case the x86_64 backend would pass it in registers by taking
                // advantage of an LLVM ABI extension that allows using 3
                // registers for the x86_64 sysv call conv rather than the
                // officially specified 2 registers.
                //
                // FIXME: Technically we should look at the amount of available
                // return registers rather than guessing that there are 2
                // registers for return values. In practice only a couple of
                // architectures have less than 2 return registers. None of
                // which supported by Cranelift.
                //
                // NOTE: This adjustment is only necessary for the Rust ABI as
                // for other ABI's the calling convention implementations in
                // rustc_target already ensure any return value which doesn't
                // fit in the available amount of return registers is passed in
                // the right way for the current target.
                //
                // The adjustment is not necessary nor desired for types with a vector
                // representation; those are handled below.
                arg.make_indirect();
                continue;
            }

            match arg.layout.backend_repr {
                BackendRepr::Memory { .. } => {
                    // Compute `Aggregate` ABI.

                    let is_indirect_not_on_stack =
                        matches!(arg.mode, PassMode::Indirect { on_stack: false, .. });
                    assert!(is_indirect_not_on_stack);

                    let size = arg.layout.size;
                    if arg.layout.is_sized()
                        && size <= Primitive::Pointer(AddressSpace::ZERO).size(cx)
                    {
                        // We want to pass small aggregates as immediates, but using
                        // an LLVM aggregate type for this leads to bad optimizations,
                        // so we pick an appropriately sized integer type instead.
                        let attr = if layout_is_noundef(arg.layout, cx) {
                            ArgAttribute::NoUndef
                        } else {
                            ArgAttribute::default()
                        };
                        arg.cast_to_with_attrs(Reg { kind: RegKind::Integer, size }, attr.into());
                    }
                }

                BackendRepr::SimdVector { .. } => {
                    // This is a fun case! The gist of what this is doing is
                    // that we want callers and callees to always agree on the
                    // ABI of how they pass SIMD arguments. If we were to *not*
                    // make these arguments indirect then they'd be immediates
                    // in LLVM, which means that they'd used whatever the
                    // appropriate ABI is for the callee and the caller. That
                    // means, for example, if the caller doesn't have AVX
                    // enabled but the callee does, then passing an AVX argument
                    // across this boundary would cause corrupt data to show up.
                    //
                    // This problem is fixed by unconditionally passing SIMD
                    // arguments through memory between callers and callees
                    // which should get them all to agree on ABI regardless of
                    // target feature sets. Some more information about this
                    // issue can be found in #44367.
                    //
                    // We *could* do better in some cases, e.g. on x86_64 targets where SSE2 is
                    // required. However, it turns out that that makes LLVM worse at optimizing this
                    // code, so we pass things indirectly even there. See #139029 for more on that.
                    if spec.simd_types_indirect {
                        arg.make_indirect();
                    }
                }

                _ => {}
            }
        }
    }
}

/// Determines whether `layout` contains no uninit bytes (no padding, no unions),
/// using only the computed layout.
///
/// Conservative: returns `false` for anything it cannot prove fully initialized,
/// including multi-variant enums and SIMD vectors.
// FIXME: extend to multi-variant enums (per-variant padding analysis needed).
fn layout_is_noundef<'a, Ty, C>(layout: TyAndLayout<'a, Ty>, cx: &C) -> bool
where
    Ty: TyAbiInterface<'a, C> + Copy,
    C: HasDataLayout,
{
    match layout.backend_repr {
        BackendRepr::Scalar(scalar) => !scalar.is_uninit_valid(),
        BackendRepr::ScalarPair(s1, s2) => {
            !s1.is_uninit_valid()
                && !s2.is_uninit_valid()
                // Ensure there is no padding.
                && s1.size(cx) + s2.size(cx) == layout.size
        }
        BackendRepr::Memory { .. } => match layout.fields {
            FieldsShape::Primitive | FieldsShape::Union(_) => false,
            // Array elements are at stride offsets with no inter-element gaps.
            FieldsShape::Array { stride: _, count } => {
                count == 0 || layout_is_noundef(layout.field(cx, 0), cx)
            }
            FieldsShape::Arbitrary { .. } => {
                // With `Variants::Multiple`, `layout.fields` only covers shared
                // bytes (niche/discriminant); per-variant data is absent, so
                // full coverage cannot be proven.
                matches!(layout.variants, Variants::Single { .. }) && fields_are_noundef(layout, cx)
            }
        },
        BackendRepr::SimdVector { .. } | BackendRepr::SimdScalableVector { .. } => false,
    }
}

/// Returns `true` if the fields of `layout` contiguously cover bytes `0..layout.size`
/// with no padding gaps and each field is recursively `layout_is_noundef`.
fn fields_are_noundef<'a, Ty, C>(layout: TyAndLayout<'a, Ty>, cx: &C) -> bool
where
    Ty: TyAbiInterface<'a, C> + Copy,
    C: HasDataLayout,
{
    let mut cursor = Size::ZERO;
    for i in layout.fields.index_by_increasing_offset() {
        let field = layout.field(cx, i);
        if field.size == Size::ZERO {
            continue;
        }
        if layout.fields.offset(i) != cursor {
            return false;
        }
        if !layout_is_noundef(field, cx) {
            return false;
        }
        cursor += field.size;
    }
    cursor == layout.size
}

// Some types are used a lot. Make sure they don't unintentionally get bigger.
#[cfg(target_pointer_width = "64")]
mod size_asserts {
    use rustc_data_structures::static_assert_size;

    use super::*;
    // tidy-alphabetical-start
    static_assert_size!(ArgAbi<'_, usize>, 56);
    static_assert_size!(FnAbi<'_, usize>, 80);
    // tidy-alphabetical-end
}
