1/* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 20// AArch64 (System V / FreeBSD) outgoing-call trampoline for the C++-UNO 21// bridge. Loads registers from caller-prepared arrays, copies overflow args 22// to the outgoing stack, performs the indirect call and stores return regs. 23 24 .text 25 .align 2 26 .globl callVirtualFunction 27 .type callVirtualFunction, @function 28callVirtualFunction: 29 .cfi_startproc 30 // prologue: save fp/lr and the callee-saved registers we use 31 stp x29, x30, [sp, #-16]! 32 stp x19, x20, [sp, #-16]! 33 stp x21, x22, [sp, #-16]! 34 stp x23, x24, [sp, #-16]! 35 mov x29, sp 36 .cfi_def_cfa x29, 64 37 .cfi_offset x29, -16 38 .cfi_offset x30, -8 39 .cfi_offset x19, -32 40 .cfi_offset x20, -24 41 .cfi_offset x21, -48 42 .cfi_offset x22, -40 43 .cfi_offset x23, -64 44 .cfi_offset x24, -56 45 46 // stash inputs that must survive the call into callee-saved registers 47 mov x19, x0 // pFunction 48 mov x20, x2 // pGPR 49 mov x21, x3 // pFPR 50 mov x22, x6 // pGPRReturn 51 mov x23, x7 // pFPRReturn 52 mov x24, x1 // x8 indirect-result value 53 54 // allocate and copy the outgoing overflow stack arguments. 55 add x9, x5, #15 56 bic x9, x9, #15 57 sub sp, sp, x9 58 mov x10, #0 59Lcvf_copy: 60 cmp x10, x5 61 b.ge Lcvf_copied 62 ldrb w11, [x4, x10] 63 strb w11, [sp, x10] 64 add x10, x10, #1 65 b Lcvf_copy 66Lcvf_copied: 67 68 // load the FP/SIMD argument registers d0..d7 69 ldp d0, d1, [x21, #0] 70 ldp d2, d3, [x21, #16] 71 ldp d4, d5, [x21, #32] 72 ldp d6, d7, [x21, #48] 73 74 // load the GP argument registers x0..x7 and the x8 indirect-result reg 75 mov x8, x24 76 ldp x6, x7, [x20, #48] 77 ldp x4, x5, [x20, #32] 78 ldp x2, x3, [x20, #16] 79 ldp x0, x1, [x20, #0] 80 81 // perform the virtual call 82 blr x19 83 84 // store the return registers 85 str x0, [x22, #0] 86 str x1, [x22, #8] 87 str d0, [x23, #0] 88 str d1, [x23, #8] 89 str d2, [x23, #16] 90 str d3, [x23, #24] 91 92 // epilogue 93 mov sp, x29 94 ldp x23, x24, [sp], #16 95 ldp x21, x22, [sp], #16 96 ldp x19, x20, [sp], #16 97 ldp x29, x30, [sp], #16 98 ret 99 .cfi_endproc 100 101// --------------------------------------------------------------------------- 102// privateSnippetExecutor: incoming (cpp2uno) register-spill executor. 103 104 .globl privateSnippetExecutor 105 .type privateSnippetExecutor, @function 106privateSnippetExecutor: 107 .cfi_startproc 108 mov x17, sp // x17 = ovrflw (incoming stack args) 109 stp x29, x30, [sp, #-176]! 110 mov x29, sp 111 .cfi_def_cfa x29, 176 112 .cfi_offset x29, -176 113 .cfi_offset x30, -168 114 115 stp x0, x1, [sp, #16] // save GP argument registers x0..x7 116 stp x2, x3, [sp, #32] 117 stp x4, x5, [sp, #48] 118 stp x6, x7, [sp, #64] 119 120 stp d0, d1, [sp, #80] // save FP/SIMD argument registers d0..d7 121 stp d2, d3, [sp, #96] 122 stp d4, d5, [sp, #112] 123 stp d6, d7, [sp, #128] 124 125 mov w0, w16 // nFunctionIndex (low 32 bits) 126 lsr x1, x16, #32 // nVtableOffset (high 32 bits) 127 add x2, sp, #16 // gpreg 128 add x3, sp, #80 // fpreg 129 mov x4, x17 // ovrflw 130 mov x5, x8 // pIndirectReturn (x8 indirect-result reg) 131 add x6, sp, #144 // pRegisterReturn (32-byte buffer) 132 bl cpp_vtable_call 133 134 cmp w0, #0x100 // RETURN_KIND_HFA_FLOAT 135 b.eq Lpse_hfa_float 136 cmp w0, #0x101 // RETURN_KIND_HFA_DOUBLE 137 b.eq Lpse_hfa_double 138 cmp w0, #10 // typelib_TypeClass_FLOAT 139 b.eq Lpse_float 140 cmp w0, #11 // typelib_TypeClass_DOUBLE 141 b.eq Lpse_float 142 cmp w0, #3 // typelib_TypeClass_BYTE 143 b.eq Lpse_signed_byte 144 cmp w0, #4 // typelib_TypeClass_SHORT 145 b.eq Lpse_signed_short 146 cmp w0, #1 // typelib_TypeClass_VOID 147 b.eq Lpse_void 148 149 // integer / pointer return 150 ldr x0, [x6, #0] 151 ldr x1, [x6, #8] 152 ldr d0, [x6, #16] 153 ldr d1, [x6, #24] 154 b Lpse_finish 155 156Lpse_hfa_float: 157 // HFA float: up to 4 floats in d0..d3 158 ldr d0, [x6, #0] 159 ldr d1, [x6, #8] 160 ldr d2, [x6, #16] 161 ldr d3, [x6, #24] 162 b Lpse_finish 163 164Lpse_hfa_double: 165 // HFA double: up to 4 doubles in d0..d3 166 ldr d0, [x6, #0] 167 ldr d1, [x6, #8] 168 ldr d2, [x6, #16] 169 ldr d3, [x6, #24] 170 b Lpse_finish 171 172Lpse_float: 173 // single float/double returned in d0 174 ldr d0, [x6, #16] 175 b Lpse_finish 176 177Lpse_signed_byte: 178 ldr x0, [x6, #0] 179 b Lpse_finish 180 181Lpse_signed_short: 182 ldr x0, [x6, #0] 183 b Lpse_finish 184 185Lpse_void: 186 mov x0, #0 187 b Lpse_finish 188 189Lpse_finish: 190 ldp x23, x24, [sp], #16 191 ldp x21, x22, [sp], #16 192 ldp x19, x20, [sp], #16 193 ldp x29, x30, [sp], #16 194 ret 195 .cfi_endproc 196 197 .section .note.GNU-stack,"",@progbits 198