Fix build on sparc64-linux-gnu.
[official-gcc.git] / libffi / src / nios2 / sysv.S
blob75f442bbeeb9bb9d2f5b3cb40b617ecface12263
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:
12    
13    The above copyright notice and this permission notice shall be
14    included in all copies or substantial portions of the Software.
15    
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 *),
27                                 extended_cif *ecif,
28                                 unsigned nbytes, 
29                                 void (*fn) (void));
30         
31    On input, the arguments appear as
32         r4 = arghook
33         r5 = ecif
34         r6 = nbytes
35         r7 = fn
38         .section        .text
39         .align  2
40         .global ffi_call_sysv
41         .type   ffi_call_sysv, @function
43 ffi_call_sysv:
44         .cfi_startproc
46         /* Create the stack frame, saving r16 so we can use it locally.  */
47         addi    sp, sp, -12
48         .cfi_def_cfa_offset 12
49         stw     ra, 8(sp)
50         stw     fp, 4(sp)
51         stw     r16, 0(sp)
52         .cfi_offset 31, -4
53         .cfi_offset 28, -8
54         .cfi_offset 16, -12
55         mov     fp, sp
56         .cfi_def_cfa_register 28
57         mov     r16, r7
59         /* Adjust the stack pointer to create the argument buffer
60            nbytes long.  */
61         sub     sp, sp, r6
63         /* Call the arghook function.  */
64         mov     r2, r4          /* fn */
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.  */
70         ldw     r4, 0(sp)
71         ldw     r5, 4(sp)
72         ldw     r6, 8(sp)
73         ldw     r7, 12(sp)
74         addi    sp, sp, 16
76         /* Call the user function, which leaves its result in r2 and r3.  */
77         callr   r16
79         /* Pop off the stack frame.  */
80         mov     sp, fp
81         ldw     ra, 8(sp)
82         ldw     fp, 4(sp)
83         ldw     r16, 0(sp)
84         addi    sp, sp, 12
85         ret
86         .cfi_endproc
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.  */
95    
96         .section        .text
97         .align  2
98         .global ffi_closure_sysv
99         .type   ffi_closure_sysv, @function
101 ffi_closure_sysv:
102         .cfi_startproc
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.  */
108         addi    sp, sp, -20
109         .cfi_def_cfa_offset 20
110         stw     ra, 0(sp)
111         .cfi_offset 31, -20
112         stw     r4, 4(sp)
113         .cfi_offset 4, -16
114         stw     r5, 8(sp)
115         .cfi_offset 5, -12
116         stw     r6, 12(sp)
117         .cfi_offset 6, -8
118         stw     r7, 16(sp)
119         .cfi_offset 7, -4
121         /* Call the helper.
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) */
125         addi    r4, sp, 4
126         mov     r5, r10
127         callr   r9
128         
129         /* Pop the stack and return.  */
130         ldw     ra, 0(sp)
131         addi    sp, sp, 20
132         .cfi_def_cfa_offset -20
133         ret
134         .cfi_endproc
135         .size   ffi_closure_sysv, .-ffi_closure_sysv