llvm-capstone/lld/test/ELF/ppc64-restgpr0.s
Fangrui Song bae7cf6746 [ELF][PPC64] Synthesize _savegpr[01]_{14..31} and _restgpr[01]_{14..31}
In the 64-bit ELF V2 API Specification: Power Architecture, 2.3.3.1. GPR
Save and Restore Functions defines some special functions which may be
referenced by GCC produced assembly (LLVM does not reference them).

With GCC -Os, when the number of call-saved registers exceeds a certain
threshold, GCC generates `_savegpr0_* _restgpr0_*` calls and expects the
linker to define them. See
https://sourceware.org/pipermail/binutils/2002-February/017444.html and
https://sourceware.org/pipermail/binutils/2004-August/036765.html . This
is weird because libgcc.a would be the natural place. However, the linker
generation approach has the advantage that the linker can generate
multiple copies to avoid long branch thunks. We don't consider the
advantage significant enough to complicate our trunk implementation, so
we take a simple approach.

* Check whether `_savegpr0_{14..31}` are used
* If yes, define needed symbols and add an InputSection with the code sequence.

`_savegpr1_*` `_restgpr0_*` and `_restgpr1_*` are similar.

Reviewed By: sfertile

Differential Revision: https://reviews.llvm.org/D79977
2020-05-26 09:35:41 -07:00

39 lines
1.1 KiB
ArmAsm

# REQUIRES: ppc
## Test code sequences of synthesized _restgpr0_{14..31}
# RUN: llvm-mc -filetype=obj -triple=ppc64le %s -o %t14.o
# RUN: ld.lld %t14.o -o %t14
# RUN: llvm-objdump -d %t14 | FileCheck --check-prefix=R14 %s
# R14-LABEL: <_restgpr0_14>:
# R14-NEXT: ld 14, -144(1)
# R14-NEXT: ld 15, -136(1)
# R14-EMPTY:
# R14-NEXT: <_restgpr0_16>:
# R14-NEXT: ld 16, -128(1)
# R14: ld 31, -8(1)
# R14-NEXT: ld 0, 16(1)
# R14-NEXT: mtlr 0
# R14-NEXT: blr
## Don't synthesize _restgpr0_{14..30} because they are unused.
# RUN: echo 'bl _restgpr0_31' | llvm-mc -filetype=obj -triple=ppc64 - -o %t31.o
# RUN: ld.lld %t31.o -o %t31
# RUN: llvm-objdump -d %t31 | FileCheck --check-prefix=R31 %s
# R31-LABEL: Disassembly of section .text:
# R31-EMPTY:
# R31-NEXT: <_restgpr0_31>:
# R31-NEXT: ld 31, -8(1)
# R31-NEXT: ld 0, 16(1)
# R31-NEXT: mtlr 0
# R31-NEXT: blr
# RUN: echo 'bl _restgpr0_32' | llvm-mc -filetype=obj -triple=ppc64 - -o %t32.o
# RUN: not ld.lld %t32.o -o /dev/null
.globl _start
_start:
bl _restgpr0_14
bl _restgpr0_16