Register Convention
This section defines which architectural state survives an ordinary C call. Argument and result locations are defined by the assignment procedure in Section 5; that procedure is their sole definition.
Register Preservation
The caller shall preserve any live value held in a volatile register before a call. A callee that modifies a nonvolatile register shall restore its exact incoming value before returning. Volatile registers carry explicitly assigned call results and caller-managed live values across the call.
C Call Preservation Sets
| State | Volatile across a call | Preserved by the callee |
|---|---|---|
| General registers | R0–R7 |
R8–R15 |
| Floating-point registers | F0–F7 |
F8–F15 |
| Vector registers | V0–V15 |
V16–V31 |
| Predicate registers | P0–P7 |
P8–P15 |
| Condition state | FLAGS |
none |
| Segment state | GS1–GS5 |
CS, DS, SS, GS0 |
A callee may preserve floating-point registers with FPUSHP and FPOPP or with any sequence having the same observable effect. Each instruction operates on one canonical pair. The nonvolatile pairs are index 4 for F8:F9, index 5 for F10:F11, index 6 for F12:F13, and index 7 for F14:F15. When several pairs are saved, a normal prologue pushes them in increasing pair-index order and the matching epilogue pops them in decreasing pair-index order. A callee need only save the pair containing each nonvolatile register it modifies.
A callee that modifies a nonvolatile vector or predicate register shall restore that register’s complete scalable image before returning. Saving only the currently active lanes, only significant predicate bits for one element size, or a fixed-width prefix represents a partial save; preservation requires the complete scalable image.
Stack and Control State
SP is the dedicated architectural stack pointer. A callee may move it while executing but shall restore the entry value before returning; Section 5 defines the additional alignment and frame rules. PC is the architectural program counter and is visible to C code only as a control-flow target. The call and return instructions define its transition across a call. Condition codes in FLAGS are volatile and may be clobbered by every callee.
Segment Context
An ordinary C call preserves the exact incoming images of CS, DS, SS, and GS0. The first three establish the code, ordinary-data, and stack contexts. GS0 establishes the TLS context and may use translated-window mode. GS1 through GS5 are caller-saved scratch segment registers; callers preserve any live incoming values they hold.
C Address-Space Context
Ordinary object and function pointers are stable 64-bit pre-segment coordinates. Every C ABI execution path maintains the following invariants:
-
While a pointer is live, calls, returns, register or memory preservation, context transitions, and ABI boundaries preserve its 64-bit coordinate.
-
Every ABI-permitted segment path that dereferences a valid object pointer selects the same byte of the same C object for a given pointer value. This includes a stack object’s address after it escapes to an ordinary data path, and a materialized TLS object’s address.
-
Pointer equality, subtraction, and in-object arithmetic have the same C result on every ABI-permitted path. A one-past pointer participates in those operations and is an arithmetic boundary sentinel. Storage accesses use coordinates within the object.
-
Function pointers, call entries, return continuations, ELF symbols and relocations, dynamic linkage, stack pointers, runtime-provided pointers, TLS materialization, signal and nonlocal-jump contexts, unwind records, and debugger-visible coordinates use this pre-segment coordinate system.
-
Segment and page-table context transitions preserve these invariants as one architectural transition from the program’s perspective.
-
Every C object and its one-past coordinate must be representable as a nonzero 64-bit address, including its one-past coordinate. The greatest representable one-past coordinate is \(2^{64}-1\).
The 64-bit all-zero null-pointer representation designates the null pointer. Every C object and function occupies a nonzero address.
Status Registers
Target-specific intrinsics and runtime code provide C access to STATUS. Low-level access to FSTATUS and FFLAGS uses <bedrockfpuintrin.h>. FSTATUS is callee-saved: a function returns with the incoming rounding mode, floating-point exception-condition enables, and other control fields. A documented floating-point-environment interface instead specifies its outgoing environment explicitly. FFLAGS is cumulative floating-point status and is caller-clobbered; floating-point operations in a callee may set accrued floating-point exception flags. An interface that requires a saved environment uses its floating-point environment runtime contract explicitly.