2020-10-26 23:48:01 +08:00
|
|
|
/* Record the register state before and after a variant PCS call.
|
2023-01-07 05:08:04 +08:00
|
|
|
Copyright (C) 2020-2023 Free Software Foundation, Inc.
|
2020-10-26 23:48:01 +08:00
|
|
|
|
|
|
|
This file is part of the GNU C Library.
|
|
|
|
|
|
|
|
The GNU C Library is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU Lesser General Public License as
|
|
|
|
published by the Free Software Foundation; either version 2.1 of the
|
|
|
|
License, or (at your option) any later version.
|
|
|
|
|
|
|
|
The GNU C Library is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
Lesser General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
|
|
License along with the GNU C Library. If not, see
|
|
|
|
<https://www.gnu.org/licenses/>. */
|
|
|
|
|
|
|
|
.variant_pcs vpcs_call
|
|
|
|
.global vpcs_call
|
|
|
|
.type vpcs_call, %function
|
|
|
|
vpcs_call:
|
|
|
|
.cfi_startproc
|
|
|
|
hint 34 /* bti c. */
|
|
|
|
|
|
|
|
/* Save register state to *x0. */
|
|
|
|
stp x0, x1, [x0]
|
|
|
|
stp x2, x3, [x0, 16]
|
|
|
|
stp x4, x5, [x0, 32]
|
|
|
|
stp x6, x7, [x0, 48]
|
|
|
|
stp x8, x9, [x0, 64]
|
|
|
|
stp x10, x11, [x0, 80]
|
|
|
|
stp x12, x13, [x0, 96]
|
|
|
|
stp x14, x15, [x0, 112]
|
|
|
|
stp x16, x17, [x0, 128]
|
|
|
|
stp x18, x19, [x0, 144]
|
|
|
|
stp x20, x21, [x0, 160]
|
|
|
|
stp x22, x23, [x0, 176]
|
|
|
|
stp x24, x25, [x0, 192]
|
|
|
|
stp x26, x27, [x0, 208]
|
|
|
|
stp x28, x29, [x0, 224]
|
|
|
|
mov x1, sp
|
|
|
|
stp x30, x1, [x0, 240]
|
|
|
|
stp q0, q1, [x0, 256]
|
|
|
|
stp q2, q3, [x0, 288]
|
|
|
|
stp q4, q5, [x0, 320]
|
|
|
|
stp q6, q7, [x0, 352]
|
|
|
|
stp q8, q9, [x0, 384]
|
|
|
|
stp q10, q11, [x0, 416]
|
|
|
|
stp q12, q13, [x0, 448]
|
|
|
|
stp q14, q15, [x0, 480]
|
|
|
|
stp q16, q17, [x0, 512]
|
|
|
|
stp q18, q19, [x0, 544]
|
|
|
|
stp q20, q21, [x0, 576]
|
|
|
|
stp q22, q23, [x0, 608]
|
|
|
|
stp q24, q25, [x0, 640]
|
|
|
|
stp q26, q27, [x0, 672]
|
|
|
|
stp q28, q29, [x0, 704]
|
|
|
|
stp q30, q31, [x0, 736]
|
|
|
|
ret
|
|
|
|
.cfi_endproc
|
|
|
|
.size vpcs_call, .-vpcs_call
|
|
|
|
|
|
|
|
.global vpcs_call_regs
|
|
|
|
.type vpcs_call_regs, %function
|
|
|
|
vpcs_call_regs:
|
|
|
|
.cfi_startproc
|
|
|
|
hint 34 /* bti c. */
|
|
|
|
|
|
|
|
stp x29, x30, [sp, -160]!
|
|
|
|
mov x29, sp
|
|
|
|
|
|
|
|
/* Save callee-saved registers. */
|
|
|
|
stp x19, x20, [sp, 16]
|
|
|
|
stp x21, x22, [sp, 32]
|
|
|
|
stp x23, x24, [sp, 48]
|
|
|
|
stp x25, x26, [sp, 64]
|
|
|
|
stp x27, x28, [sp, 80]
|
|
|
|
stp d8, d9, [sp, 96]
|
|
|
|
stp d10, d11, [sp, 112]
|
|
|
|
stp d12, d13, [sp, 128]
|
|
|
|
stp d14, d15, [sp, 144]
|
|
|
|
|
|
|
|
/* Initialize most registers from *x1, and save x0, x1, x29, x30,
|
|
|
|
and sp (== x29), so *x1 contains the register state. */
|
|
|
|
stp x0, x1, [x1]
|
|
|
|
str x29, [x1, 232]
|
|
|
|
ldp x2, x3, [x1, 16]
|
|
|
|
ldp x4, x5, [x1, 32]
|
|
|
|
ldp x6, x7, [x1, 48]
|
|
|
|
ldp x8, x9, [x1, 64]
|
|
|
|
ldp x10, x11, [x1, 80]
|
|
|
|
ldp x12, x13, [x1, 96]
|
|
|
|
ldp x14, x15, [x1, 112]
|
|
|
|
ldp x16, x17, [x1, 128]
|
|
|
|
ldp x18, x19, [x1, 144]
|
|
|
|
ldp x20, x21, [x1, 160]
|
|
|
|
ldp x22, x23, [x1, 176]
|
|
|
|
ldp x24, x25, [x1, 192]
|
|
|
|
ldp x26, x27, [x1, 208]
|
|
|
|
ldr x28, [x1, 224]
|
|
|
|
/* Skip x29, x30, sp. */
|
|
|
|
ldp q0, q1, [x1, 256]
|
|
|
|
ldp q2, q3, [x1, 288]
|
|
|
|
ldp q4, q5, [x1, 320]
|
|
|
|
ldp q6, q7, [x1, 352]
|
|
|
|
ldp q8, q9, [x1, 384]
|
|
|
|
ldp q10, q11, [x1, 416]
|
|
|
|
ldp q12, q13, [x1, 448]
|
|
|
|
ldp q14, q15, [x1, 480]
|
|
|
|
ldp q16, q17, [x1, 512]
|
|
|
|
ldp q18, q19, [x1, 544]
|
|
|
|
ldp q20, q21, [x1, 576]
|
|
|
|
ldp q22, q23, [x1, 608]
|
|
|
|
ldp q24, q25, [x1, 640]
|
|
|
|
ldp q26, q27, [x1, 672]
|
|
|
|
ldp q28, q29, [x1, 704]
|
|
|
|
ldp q30, q31, [x1, 736]
|
|
|
|
|
|
|
|
/* Emulate a BL using B, but save x30 before the branch. */
|
|
|
|
adr x30, .L_return_addr
|
|
|
|
stp x30, x29, [x1, 240]
|
|
|
|
b vpcs_call
|
|
|
|
.L_return_addr:
|
|
|
|
|
|
|
|
/* Restore callee-saved registers. */
|
|
|
|
ldp x19, x20, [sp, 16]
|
|
|
|
ldp x21, x22, [sp, 32]
|
|
|
|
ldp x23, x24, [sp, 48]
|
|
|
|
ldp x25, x26, [sp, 64]
|
|
|
|
ldp x27, x28, [sp, 80]
|
|
|
|
ldp d8, d9, [sp, 96]
|
|
|
|
ldp d10, d11, [sp, 112]
|
|
|
|
ldp d12, d13, [sp, 128]
|
|
|
|
ldp d14, d15, [sp, 144]
|
|
|
|
|
|
|
|
ldp x29, x30, [sp], 160
|
|
|
|
ret
|
|
|
|
.cfi_endproc
|
|
|
|
.size vpcs_call_regs, .-vpcs_call_regs
|