1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
| /* -----------------------------------------------------------------------
| eabi.S - Copyright (c) 2004 Anthony Green
|
| FR-V Assembly glue.
|
| Permission is hereby granted, free of charge, to any person obtaining
| a copy of this software and associated documentation files (the
| ``Software''), to deal in the Software without restriction, including
| without limitation the rights to use, copy, modify, merge, publish,
| distribute, sublicense, and/or sell copies of the Software, and to
| permit persons to whom the Software is furnished to do so, subject to
| the following conditions:
|
| The above copyright notice and this permission notice shall be included
| in all copies or substantial portions of the Software.
|
| THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
| IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
| OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
| ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
| OTHER DEALINGS IN THE SOFTWARE.
| ----------------------------------------------------------------------- */
|
| #define LIBFFI_ASM
| #include <fficonfig.h>
| #include <ffi.h>
|
| .globl ffi_prep_args_EABI
|
| .text
| .p2align 4
| .globl ffi_call_EABI
| .type ffi_call_EABI, @function
|
| # gr8 : ffi_prep_args
| # gr9 : &ecif
| # gr10: cif->bytes
| # gr11: fig->flags
| # gr12: ecif.rvalue
| # gr13: fn
|
| ffi_call_EABI:
| addi sp, #-80, sp
| sti fp, @(sp, #24)
| addi sp, #24, fp
| movsg lr, gr5
|
| /* Make room for the new arguments. */
| /* subi sp, fp, gr10 */
|
| /* Store return address and incoming args on stack. */
| sti gr5, @(fp, #8)
| sti gr8, @(fp, #-4)
| sti gr9, @(fp, #-8)
| sti gr10, @(fp, #-12)
| sti gr11, @(fp, #-16)
| sti gr12, @(fp, #-20)
| sti gr13, @(fp, #-24)
|
| sub sp, gr10, sp
|
| /* Call ffi_prep_args. */
| ldi @(fp, #-4), gr4
| addi sp, #0, gr8
| ldi @(fp, #-8), gr9
| #ifdef __FRV_FDPIC__
| ldd @(gr4, gr0), gr14
| calll @(gr14, gr0)
| #else
| calll @(gr4, gr0)
| #endif
|
| /* ffi_prep_args returns the new stack pointer. */
| mov gr8, gr4
|
| ldi @(sp, #0), gr8
| ldi @(sp, #4), gr9
| ldi @(sp, #8), gr10
| ldi @(sp, #12), gr11
| ldi @(sp, #16), gr12
| ldi @(sp, #20), gr13
|
| /* Always copy the return value pointer into the hidden
| parameter register. This is only strictly necessary
| when we're returning an aggregate type, but it doesn't
| hurt to do this all the time, and it saves a branch. */
| ldi @(fp, #-20), gr3
|
| /* Use the ffi_prep_args return value for the new sp. */
| mov gr4, sp
|
| /* Call the target function. */
| ldi @(fp, -24), gr4
| #ifdef __FRV_FDPIC__
| ldd @(gr4, gr0), gr14
| calll @(gr14, gr0)
| #else
| calll @(gr4, gr0)
| #endif
|
| /* Store the result. */
| ldi @(fp, #-16), gr10 /* fig->flags */
| ldi @(fp, #-20), gr4 /* ecif.rvalue */
|
| /* Is the return value stored in two registers? */
| cmpi gr10, #8, icc0
| bne icc0, 0, .L2
| /* Yes, save them. */
| sti gr8, @(gr4, #0)
| sti gr9, @(gr4, #4)
| bra .L3
| .L2:
| /* Is the return value a structure? */
| cmpi gr10, #-1, icc0
| beq icc0, 0, .L3
| /* No, save a 4 byte return value. */
| sti gr8, @(gr4, #0)
| .L3:
|
| /* Restore the stack, and return. */
| ldi @(fp, 8), gr5
| ld @(fp, gr0), fp
| addi sp,#80,sp
| jmpl @(gr5,gr0)
| .size ffi_call_EABI, .-ffi_call_EABI
|
|
|