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.
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: u64The 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.