1/* Record the register state before and after a variant PCS call. 2 Copyright (C) 2020-2022 Free Software Foundation, Inc. 3 4 This file is part of the GNU C Library. 5 6 The GNU C Library is free software; you can redistribute it and/or 7 modify it under the terms of the GNU Lesser General Public License as 8 published by the Free Software Foundation; either version 2.1 of the 9 License, or (at your option) any later version. 10 11 The GNU C Library is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 Lesser General Public License for more details. 15 16 You should have received a copy of the GNU Lesser General Public 17 License along with the GNU C Library. If not, see 18 <https://www.gnu.org/licenses/>. */ 19 20 .variant_pcs vpcs_call 21 .global vpcs_call 22 .type vpcs_call, %function 23vpcs_call: 24 .cfi_startproc 25 hint 34 /* bti c. */ 26 27 /* Save register state to *x0. */ 28 stp x0, x1, [x0] 29 stp x2, x3, [x0, 16] 30 stp x4, x5, [x0, 32] 31 stp x6, x7, [x0, 48] 32 stp x8, x9, [x0, 64] 33 stp x10, x11, [x0, 80] 34 stp x12, x13, [x0, 96] 35 stp x14, x15, [x0, 112] 36 stp x16, x17, [x0, 128] 37 stp x18, x19, [x0, 144] 38 stp x20, x21, [x0, 160] 39 stp x22, x23, [x0, 176] 40 stp x24, x25, [x0, 192] 41 stp x26, x27, [x0, 208] 42 stp x28, x29, [x0, 224] 43 mov x1, sp 44 stp x30, x1, [x0, 240] 45 stp q0, q1, [x0, 256] 46 stp q2, q3, [x0, 288] 47 stp q4, q5, [x0, 320] 48 stp q6, q7, [x0, 352] 49 stp q8, q9, [x0, 384] 50 stp q10, q11, [x0, 416] 51 stp q12, q13, [x0, 448] 52 stp q14, q15, [x0, 480] 53 stp q16, q17, [x0, 512] 54 stp q18, q19, [x0, 544] 55 stp q20, q21, [x0, 576] 56 stp q22, q23, [x0, 608] 57 stp q24, q25, [x0, 640] 58 stp q26, q27, [x0, 672] 59 stp q28, q29, [x0, 704] 60 stp q30, q31, [x0, 736] 61 ret 62 .cfi_endproc 63 .size vpcs_call, .-vpcs_call 64 65 .global vpcs_call_regs 66 .type vpcs_call_regs, %function 67vpcs_call_regs: 68 .cfi_startproc 69 hint 34 /* bti c. */ 70 71 stp x29, x30, [sp, -160]! 72 mov x29, sp 73 74 /* Save callee-saved registers. */ 75 stp x19, x20, [sp, 16] 76 stp x21, x22, [sp, 32] 77 stp x23, x24, [sp, 48] 78 stp x25, x26, [sp, 64] 79 stp x27, x28, [sp, 80] 80 stp d8, d9, [sp, 96] 81 stp d10, d11, [sp, 112] 82 stp d12, d13, [sp, 128] 83 stp d14, d15, [sp, 144] 84 85 /* Initialize most registers from *x1, and save x0, x1, x29, x30, 86 and sp (== x29), so *x1 contains the register state. */ 87 stp x0, x1, [x1] 88 str x29, [x1, 232] 89 ldp x2, x3, [x1, 16] 90 ldp x4, x5, [x1, 32] 91 ldp x6, x7, [x1, 48] 92 ldp x8, x9, [x1, 64] 93 ldp x10, x11, [x1, 80] 94 ldp x12, x13, [x1, 96] 95 ldp x14, x15, [x1, 112] 96 ldp x16, x17, [x1, 128] 97 ldp x18, x19, [x1, 144] 98 ldp x20, x21, [x1, 160] 99 ldp x22, x23, [x1, 176] 100 ldp x24, x25, [x1, 192] 101 ldp x26, x27, [x1, 208] 102 ldr x28, [x1, 224] 103 /* Skip x29, x30, sp. */ 104 ldp q0, q1, [x1, 256] 105 ldp q2, q3, [x1, 288] 106 ldp q4, q5, [x1, 320] 107 ldp q6, q7, [x1, 352] 108 ldp q8, q9, [x1, 384] 109 ldp q10, q11, [x1, 416] 110 ldp q12, q13, [x1, 448] 111 ldp q14, q15, [x1, 480] 112 ldp q16, q17, [x1, 512] 113 ldp q18, q19, [x1, 544] 114 ldp q20, q21, [x1, 576] 115 ldp q22, q23, [x1, 608] 116 ldp q24, q25, [x1, 640] 117 ldp q26, q27, [x1, 672] 118 ldp q28, q29, [x1, 704] 119 ldp q30, q31, [x1, 736] 120 121 /* Emulate a BL using B, but save x30 before the branch. */ 122 adr x30, .L_return_addr 123 stp x30, x29, [x1, 240] 124 b vpcs_call 125.L_return_addr: 126 127 /* Restore callee-saved registers. */ 128 ldp x19, x20, [sp, 16] 129 ldp x21, x22, [sp, 32] 130 ldp x23, x24, [sp, 48] 131 ldp x25, x26, [sp, 64] 132 ldp x27, x28, [sp, 80] 133 ldp d8, d9, [sp, 96] 134 ldp d10, d11, [sp, 112] 135 ldp d12, d13, [sp, 128] 136 ldp d14, d15, [sp, 144] 137 138 ldp x29, x30, [sp], 160 139 ret 140 .cfi_endproc 141 .size vpcs_call_regs, .-vpcs_call_regs 142