The x86_64 System V ABI in Section 3.2.3 specifies which arguments of a function call go to which registers and which are pushed on the stack. I have troubles understanding the algorithm for the classification of aggregates, which says (the highlighting is mine):
The classification of aggregate (structures and arrays) and union types works as follows:
- If the size of an object is larger than eight eightbytes, or it contains unaligned fields, it has class MEMORY.
- If a C++ object is non-trivial for the purpose of calls, as specified in the C++ ABI13, it is passed by invisible reference (the object is replaced in the parameter list by a pointer that has class INTEGER).
- If the size of the aggregate exceeds a single eightbyte, each is classified separately. Each eightbyte gets initialized to class NO_CLASS.
- Each field of an object is classified recursively so that always two fields are considered. The resulting class is calculated according to the classes of the fields in the eightbyte: (a) If both classes are equal, this is the resulting class. (b) If one of the classes is NO_CLASS, the resulting class is the other class.(c) If one of the classes is MEMORY, the result is the MEMORY class.(d) If one of the classes is INTEGER, the result is the INTEGER. (e) If one of the classes is X87, X87UP, COMPLEX_X87 class, MEMORY is used as class.(f) Otherwise class SSE is used.
- Then a post merger cleanup is done: (a) If one of the classes is MEMORY, the whole argument is passed in memory. (b) If X87UP is not preceded by X87, the whole argument is passed in memory. (c) If the size of the aggregate exceeds two eightbytes and the first eightbyte isn’t SSE or any other eightbyte isn’t SSEUP, the whole argument is passed in memory. (d) If SSEUP is not preceded by SSE or SSEUP, it is converted to SSE
I do not understand points (3), (4), and (5). Specifically, I have the following questions:
Q1. In point (3), by "each is classified separately", do authors mean "each eightbyte"? If so, then I would expect that what follows is an explanation of classification of eightbytes.
Q2. In point (4), by "Each field of an object", do they mean "each field of an eightbyte that is a result of (separation in) point (3)?
Q3. In point (4), by "two fields" in "always two fields are considered", do they mean two successive fields?
Q4. In point (4), by "the resulting class", do they mean the class of the object, or of the eightbyte, or of the second considered field, or of something else? In the last case, where is the resulting class used? Does this mean that the algorithm keeps the field of the first field as is, and then iteratively computes the class of the next field, until we have the classes of all fields in the eightbyte? Or does it mean that we the algorithm processes two fields at once?
Q5. In point (4), what if there is only one field? Or an even number of fields?
Q6. In point (5), "one of the classes" of a field, or of an eightbyte?
If someone could provide something more formal/precise - e.g., a pseudo-code or a flow-chart - that would be ideal.