xref: /trunk/main/bridges/source/cpp_uno/gcc3_freebsd_aarch64/call.s (revision 9c15e1abd703a7953928d7a80655ae1a76a41f6d)
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