Skip to content

[aapcs64] Standardize on "caller-saved" and "callee-saved"#371

Merged
smithp35 merged 1 commit into
ARM-software:mainfrom
AlfieRichardsArm:main
Mar 12, 2026
Merged

[aapcs64] Standardize on "caller-saved" and "callee-saved"#371
smithp35 merged 1 commit into
ARM-software:mainfrom
AlfieRichardsArm:main

Conversation

@AlfieRichardsArm
Copy link
Copy Markdown
Contributor

This addresses some issues raised in #266 by standardizing on
"callee-saved" and "caller-saved" for describing register preservation
rules in PCS.

For now this only applies to AAPCS64.

Copy link
Copy Markdown
Contributor

@smithp35 smithp35 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo in the title (Stadardize -> Standardize)

Will be worth getting some wider input on whether standardising on caller-saved and callee-saved is the best choice.

FWIW despite its problems, like only having one letter difference in names, I'm happy with caller/callee saved as that seems to be the most commonly used term on the most active ABIs.

What I could check:
x86_64 caller/callee saved.
RISCV caller/callee saved.
GO caller/callee saved [1]
PPC volatile/non-volatile.
Sparc volatile.
Microsoft (including ARM64EC [2]) volatile/non-volatile

I couldn't find any saying call-preserved or call-clobbered, but I did find explanatory text that said preserved across calls.

[1] https://go.googlesource.com/go/+/refs/heads/master/src/cmd/compile/abi-internal.md (actually all caller-saved)
[2] https://learn.microsoft.com/en-us/cpp/build/arm64ec-windows-abi-conventions https://learn.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-180

Comment thread aapcs64/aapcs64.rst Outdated
Comment thread aapcs64/aapcs64.rst Outdated
Comment thread aapcs64/aapcs64.rst Outdated
Comment thread aapcs64/aapcs64.rst Outdated
Comment thread aapcs64/aapcs64.rst Outdated
Comment thread vfabia64/vfabia64.rst
Comment thread 0001-aapcs64-Stadardize-on-caller-saved-and-callee-saved.patch Outdated
Comment thread aapcs64/aapcs64.rst Outdated
above. Informally, the scheme allows “ZA is callee-saved” to become a
dynamic rather than a static property: if S2 `complies with the lazy saving
scheme`_, S1 can test after the call to S2 whether the call did in fact
preserve ZA. If the call did not preserve ZA, S1 is able to restore the
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As an aside. I tried to see if I could reword this in terms of callee-save but I don't think it can be. One of the advantages of preserve rather than save, is that callee-save is really callee-responsible-for-save, not that it must save, and preserve captures that.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, I think this is also relevant for Georges comment on FFR where I am hesitant to say "caller-saved" because I think it implies the wrong thing.

Comment thread aapcs64/aapcs64.rst Outdated
Comment thread aapcs64/aapcs64.rst Outdated
The first eight registers, v0-v7, are used to pass argument values into a subroutine and to return result values from a function. They may also be used to hold intermediate values within a routine (but, in general, only between subroutine calls).

Registers v8-v15 must be preserved by a callee across subroutine calls; the remaining registers (v0-v7, v16-v31) do not need to be preserved (or should be preserved by the caller). Additionally, only the bottom 64 bits of each value stored in v8-v15 need to be preserved [#aapcs64-f7]_; it is the responsibility of the caller to preserve larger values.
Registers v8-v15 are callee-saved across subroutine calls; the remaining registers (v0-v7, v16-v31) do not need to be preserved (or should be preserved by the caller). Additionally, only the bottom 64 bits of each value stored in v8-v15 need to be preserved [#aapcs64-f7]_; it is the responsibility of the caller to preserve larger values.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really see the need to change this phrase, it's completely clear and flows better with the second part of the sentence ("must be preserved"/"do not need to be preserved").

Generally, I would suggest standardising to "caller-saved"/"calle-saved" instead of using other adjectives, or if there's ambiguity, but not replace any phrase that speaks about (not) preserving.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree in principle but I think this case is re-describing what "callee-saved" means so could be confusing to not use the term we standardize on?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have updated this and the surrounding section to only use "callee-saved" and "caller-saved" to refer to preservation of registers.

I do agree that these sections flow worse after these changes, but I think the change to be consistent is worth it overall. But I would be grateful for your feedback.

Comment thread vfabia64/vfabia64.rst Outdated
Comment thread aapcs64/aapcs64.rst Outdated
Comment thread aapcs64/aapcs64.rst Outdated
Comment thread aapcs64/aapcs64.rst Outdated
@AlfieRichardsArm AlfieRichardsArm changed the title [aapcs64] Stadardize on "caller-saved" and "callee-saved" [aapcs64] Standardize on "caller-saved" and "callee-saved" Mar 3, 2026
@AlfieRichardsArm
Copy link
Copy Markdown
Contributor Author

Just to add. I just noticed several places use "temporary register". This seems to mean "caller-saved" but come with some extra meaning too. Thoughts on changing these uses as well?

There is a separate definition which I have merged with the caller-saved one for the next patch.

@AlfieRichardsArm
Copy link
Copy Markdown
Contributor Author

AlfieRichardsArm commented Mar 3, 2026

Rebased onto #373 (the fix of typos noticed by Peter)

Comment thread aapcs64/aapcs64.rst Outdated
Copy link
Copy Markdown
Contributor

@smithp35 smithp35 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only a few small comments from me. This is looking close.

Comment thread aapcs64/aapcs64.rst Outdated
Comment thread aapcs64-morello/aapcs64-morello.rst Outdated
Comment thread aapcs64/aapcs64.rst Outdated
Comment thread vfabia64/vfabia64.rst Outdated
@richfelker
Copy link
Copy Markdown

I'm an outsider on this, but as author/maintainer of musl libc and someone involved in multiple platforms' ABI stuff, I believe this is a change in the opposite direction of what we should be making. "Call-saved" and "call-clobbered" are the actual semantics here: per the ABI, does making a call require treating these registers as clobbered, or can they be assumed to be preserved?

"Callee-saved" vs "caller-saved" presumes the presence of valuable information and that one party of the other has an obligation to save that. This is normally not the case. A callee never has an obligation to save anything it's not touching, and a caller never has any obligation to save something whose value it will not use again.

Comment thread vfabia64/vfabia64.rst

+-------------+--------------------+--------------+--------------+
|Extension |Parameter and Result|Call-clobbered|Call-preserved|
|Extension |Parameter and Result|Caller-saved |Callee-saved |
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO 'call-clobbered' and 'call-preserved' are much better terms. 'Caller-saved' and 'callee-saved' are only a letter apart, making them unnecessarily easy to mix up when reading quickly...

Copy link
Copy Markdown

@richfelker richfelker Mar 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'Caller-saved' and 'callee-saved' are only a letter apart, making them unnecessarily easy to mix up when reading quickly...

This is indeed another very good reason to prefer the call-clobbered/call-preserved terminology.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'Caller-saved' and 'callee-saved' are only a letter apart, making them unnecessarily easy to mix up when reading quickly...

This is indeed another very good reason to prefer the call-clobbered/call-preserved terminology.

Case in point: #385

@momchil-velikov
Copy link
Copy Markdown
Contributor

Out compiler engineer bias might be showing here, but I'm under the subjective impression that "callee-saved" and "caller-saved" are much more established terms in the community and the literature.

FWIW, I did a quick search in ACM DL:

  • "call-clobbered": 0 results
  • "call-preserved": 7 results
  • "callee-saved": 285 results
  • "caller-saved": 186 results

Comment thread aapcs64/aapcs64.rst Outdated
* X2-X15, X19-X29 and SP are call-preserved.
* Z0-Z31 are call-preserved.
* P0-P15 are call-preserved.
* X2-X15, X19-X29 and SP are callee-saved.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since there was some confusion about this recently, we should explicitly state these private helpers must not clobber X18 (since it is reserved and has various uses). GCC currently treats X18 as clobbered by these helpers, which interferes with some uses of X18.

This also applies to the other helpers below.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the review. I may do this in another patch if that's okay with you? Keep this one "no functional change intended"?

Copy link
Copy Markdown
Contributor

@smithp35 smithp35 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the updates. I'm happy all other existing comments from me have been addressed.

On the caller-saved/callee-saved vs call-preserved/call-clobbered question.

I think what we have now is an awkward mix of the two terms, which is the worse situation. Standardising on one way, even if it is not our preference is a step in the right direction.

I do agree that there are advantages to call-preserved and call-clobbered that have been mentioned already. There are also advantages to caller and callee-saved, mostly that they are the most commonly used terms in ABIs, including historically the Arm and AArch64 ABIs and the compiler literature.

I think we should go ahead with this PR. Leaving the door open for a change to call-preserved, call-clobbered if that term becomes more widely used, or there is a consensus internally and externally that it is worth changing. We'll at least be starting from a consistent base at that point.

Comment thread aapcs64/aapcs64.rst
Copy link
Copy Markdown
Contributor

@smithp35 smithp35 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the addition of the links. I've no more comments and have given it my +1 with Approve.

We should leave this open for at least a week for any further comments from other reviewers.

smithp35 pushed a commit that referenced this pull request Mar 12, 2026
This addresses the unrelated typos found in review of #371 noticed by
Peter Smith.
@smithp35
Copy link
Copy Markdown
Contributor

@AlfieRichardsArm I've merged #373 I think this needs rebasing. As there have been no more comments since last week I can merge this once it has been rebased.

@AlfieRichardsArm
Copy link
Copy Markdown
Contributor Author

@smithp35 Rebased now, thanks for your help with this!

@smithp35 smithp35 merged commit e2534ac into ARM-software:main Mar 12, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants