mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-11 17:08:42 +00:00
bae7cf6746
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
32 lines
1.1 KiB
ArmAsm
32 lines
1.1 KiB
ArmAsm
# REQUIRES: ppc
|
|
## Test that some save and restore functions can be synthesized.
|
|
## The code sequences are tested by ppc64-restgpr*.s and ppc64-savegpr*.s
|
|
|
|
# RUN: llvm-mc -filetype=obj -triple=ppc64le %s -o %t.o
|
|
# RUN: ld.lld -shared %t.o -o %t.so
|
|
# RUN: llvm-readelf -s %t.so | FileCheck --check-prefix=NM %s
|
|
# RUN: llvm-objdump -d %t.so | FileCheck %s
|
|
|
|
## The synthesized symbols are not exported.
|
|
# NM: FUNC LOCAL HIDDEN {{.*}} _restgpr0_30
|
|
# NM-NEXT: FUNC LOCAL HIDDEN {{.*}} _restgpr1_30
|
|
# NM-NEXT: FUNC LOCAL HIDDEN {{.*}} _savegpr0_30
|
|
# NM-NEXT: FUNC LOCAL HIDDEN {{.*}} _savegpr1_30
|
|
|
|
# CHECK: 00000000000[[#%x,RESTGPR0:]] <_restgpr0_30>:
|
|
# CHECK: 00000000000[[#%x,RESTGPR1:]] <_restgpr1_30>:
|
|
# CHECK: 00000000000[[#%x,SAVEGPR0:]] <_savegpr0_30>:
|
|
# CHECK: 00000000000[[#%x,SAVEGPR1:]] <_savegpr1_30>:
|
|
# CHECK-LABEL: <_start>:
|
|
# CHECK-NEXT: bl 0x[[#RESTGPR0]]
|
|
# CHECK-NEXT: bl 0x[[#RESTGPR1]]
|
|
# CHECK-NEXT: bl 0x[[#SAVEGPR0]]
|
|
# CHECK-NEXT: bl 0x[[#SAVEGPR1]]
|
|
|
|
.globl _start
|
|
_start:
|
|
bl _restgpr0_30
|
|
bl _restgpr1_30
|
|
bl _savegpr0_30
|
|
bl _savegpr1_30
|