1 /* Low-level libffi support for Altera Nios II.
3 Copyright (c) 2013 Mentor Graphics.
5 Permission is hereby granted, free of charge, to any person obtaining
6 a copy of this software and associated documentation files (the
7 ``Software''), to deal in the Software without restriction, including
8 without limitation the rights to use, copy, modify, merge, publish,
9 distribute, sublicense, and/or sell copies of the Software, and to
10 permit persons to whom the Software is furnished to do so, subject to
11 the following conditions:
13 The above copyright notice and this permission notice shall be
14 included in all copies or substantial portions of the Software.
16 THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
17 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
24 /* This function is declared on the C side as
26 extern UINT64 ffi_call_sysv (void (*arghook) (char *, extended_cif *),
31 On input, the arguments appear as
41 .type ffi_call_sysv, @function
46 /* Create the stack frame, saving r16 so we can use it locally. */
48 .cfi_def_cfa_offset 12
56 .cfi_def_cfa_register 28
59 /* Adjust the stack pointer to create the argument buffer
63 /* Call the arghook function. */
65 mov r4, sp /* argbuffer */
66 callr r2 /* r5 already contains ecif */
68 /* Pop off the first 16 bytes of the argument buffer on the stack,
69 transferring the contents to the argument registers. */
76 /* Call the user function, which leaves its result in r2 and r3. */
79 /* Pop off the stack frame. */
87 .size ffi_call_sysv, .-ffi_call_sysv
90 /* Closure trampolines jump here after putting the C helper address
91 in r9 and the closure pointer in r10. The user-supplied arguments
92 to the closure are in the normal places, in r4-r7 and on the
93 stack. Push the register arguments on the stack too and then call the
94 C helper function to deal with them. */
98 .global ffi_closure_sysv
99 .type ffi_closure_sysv, @function
104 /* Create the stack frame, pushing the register args on the stack
105 just below the stack args. This is the same trick illustrated
106 in Figure 7-3 in the Nios II Processor Reference Handbook, used
107 for variable arguments and structures passed by value. */
109 .cfi_def_cfa_offset 20
122 r4 = pointer to arguments on stack
123 r5 = closure pointer (loaded in r10 by the trampoline)
124 r9 = address of helper function (loaded by trampoline) */
129 /* Pop the stack and return. */
132 .cfi_def_cfa_offset -20
135 .size ffi_closure_sysv, .-ffi_closure_sysv