Skip to main content

Test

Enum Test 

Source
pub enum Test {
    Anything,
    Empty,
    SizeOneOf(&'static [u64]),
    SizeAtMost(u64),
    Homogeneous {
        limit: usize,
    },
    FloatPair,
    X87Stack,
    Eightbytes {
        limit: u64,
    },
}
Expand description

What an aggregate has to look like for a rule to apply.

Four of these look inside the aggregate and the rest read its size. The four are the mechanisms of this crate, and the claim in section 6.7 is that the number of them grows much more slowly than the number of ABIs.

Variants§

§

Anything

Anything, which is what the last rule in a list is.

§

Empty

An aggregate of no size, which is a GNU empty struct and travels nowhere.

§

SizeOneOf(&'static [u64])

A size that is exactly one of these.

Windows x64’s rule, and the sharpest one on the list: anything not exactly one, two, four or eight bytes travels as an address, so a three byte structure and a three hundred byte structure are passed the same way. Also s390x’s, with the same list.

§

SizeAtMost(u64)

A size at most this many bytes.

§

Homogeneous

A homogeneous floating point aggregate of at most this many members.

AAPCS64’s HFA, and the same idea with a different limit on AAPCS32 hard float and on ELFv2. Homogeneous means every scalar in it is the same floating point type once arrays and nested records are flattened, and that they fill the aggregate with no padding left over. The second half is what rules out struct { float a; char pad[8]; } and anything a zero width bit-field has stretched.

Fields

§limit: usize

The most members it can have and still travel in vector registers.

§

FloatPair

One or two members with at least one floating point member between them, each fitting one register.

The RISC-V rule, and LoongArch’s. struct { double re, im; } is two floating point registers and struct { double value; int tag; } is one of each, which no other ABI on the list does. A member wider than a floating point register is not a floating point member for this purpose, which is what makes a long double here behave like an integer pair.

§

X87Stack

Every scalar is an x87 long double, and there is one of them, or two if it is a _Complex.

The SysV return path, where a long double comes back in st(0) and a _Complex long double in st(0) and st(1). A record holding two of them is the same thirty two bytes and comes back in memory, which is the only thing crate::Shape::complex is for.

§

Eightbytes

The SysV eightbyte classification succeeds, and no eightbyte came out x87.

The intricate one. The aggregate is cut into eight byte chunks, each chunk gets a class from merging the classes of every scalar reaching into it, and any chunk that comes out MEMORY takes the whole argument to memory with it. The cases that catch people are all in the merge: an eightbyte holding an int and a float together is INTEGER, so the float travels in a general purpose register, and a member away from its natural alignment sends the whole thing to memory.

Fields

§limit: u64

The largest aggregate that can be classified at all, sixteen bytes on SysV.

It is a consequence of the eight eightbyte limit rather than an independent rule: an aggregate over two eightbytes travels in registers only when every eightbyte after the first is SSEUP, and only a vector produces those.

Trait Implementations§

Source§

impl Clone for Test

Source§

fn clone(&self) -> Test

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Copy for Test

Source§

impl Debug for Test

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Eq for Test

Source§

impl PartialEq for Test

Source§

fn eq(&self, other: &Test) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for Test

Auto Trait Implementations§

§

impl Freeze for Test

§

impl RefUnwindSafe for Test

§

impl Send for Test

§

impl Sync for Test

§

impl Unpin for Test

§

impl UnsafeUnpin for Test

§

impl UnwindSafe for Test

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.