Skip to content

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 R0R7 R8R15
Floating-point registers F0F7 F8F15
Vector registers V0V15 V16V31
Predicate registers P0P7 P8P15
Condition state FLAGS none
Segment state GS1GS5 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.