1/* ----------------------------------------------------------------------- 2 sysv.S - Copyright (c) 2009 Bradley Smith <brad@brad-smith.co.uk> 3 4 AVR32 Foreign Function Interface 5 6 Permission is hereby granted, free of charge, to any person obtaining 7 a copy of this software and associated documentation files (the 8 ``Software''), to deal in the Software without restriction, including 9 without limitation the rights to use, copy, modify, merge, publish, 10 distribute, sublicense, and/or sell copies of the Software, and to 11 permit persons to whom the Software is furnished to do so, subject to 12 the following conditions: 13 14 The above copyright notice and this permission notice shall be included 15 in all copies or substantial portions of the Software. 16 17 THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 18 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 --------------------------------------------------------------------- */ 25 26#define LIBFFI_ASM 27#include <fficonfig.h> 28#include <ffi.h> 29 30 /* r12: ffi_prep_args 31 * r11: &ecif 32 * r10: size 33 * r9: cif->flags 34 * r8: ecif.rvalue 35 * sp+0: cif->rstruct_flag 36 * sp+4: fn */ 37 38 .text 39 .align 1 40 .globl ffi_call_SYSV 41 .type ffi_call_SYSV, @function 42ffi_call_SYSV: 43 stm --sp, r0,r1,lr 44 stm --sp, r8-r12 45 mov r0, sp 46 47 /* Make room for all of the new args. */ 48 sub sp, r10 49 /* Pad to make way for potential skipped registers */ 50 sub sp, 20 51 52 /* Call ffi_prep_args(stack, &ecif). */ 53 /* r11 already set */ 54 mov r1, r12 55 mov r12, sp 56 icall r1 57 58 /* Save new argument size */ 59 mov r1, r12 60 61 /* Move first 5 parameters in registers. */ 62 ldm sp++, r8-r12 63 64 /* call (fn) (...). */ 65 ld.w r1, r0[36] 66 icall r1 67 68 /* Remove the space we pushed for the args. */ 69 mov sp, r0 70 71 /* Load r1 with the rstruct flag. */ 72 ld.w r1, sp[32] 73 74 /* Load r9 with the return type code. */ 75 ld.w r9, sp[12] 76 77 /* Load r8 with the return value pointer. */ 78 ld.w r8, sp[16] 79 80 /* If the return value pointer is NULL, assume no return value. */ 81 cp.w r8, 0 82 breq .Lend 83 84 /* Check if return type is actually a struct */ 85 cp.w r1, 0 86 breq 1f 87 88 /* Return 8bit */ 89 cp.w r9, FFI_TYPE_UINT8 90 breq .Lstore8 91 92 /* Return 16bit */ 93 cp.w r9, FFI_TYPE_UINT16 94 breq .Lstore16 95 961: 97 /* Return 32bit */ 98 cp.w r9, FFI_TYPE_UINT32 99 breq .Lstore32 100 cp.w r9, FFI_TYPE_UINT16 101 breq .Lstore32 102 cp.w r9, FFI_TYPE_UINT8 103 breq .Lstore32 104 105 /* Return 64bit */ 106 cp.w r9, FFI_TYPE_UINT64 107 breq .Lstore64 108 109 /* Didn't match anything */ 110 bral .Lend 111 112.Lstore64: 113 st.w r8[0], r11 114 st.w r8[4], r10 115 bral .Lend 116 117.Lstore32: 118 st.w r8[0], r12 119 bral .Lend 120 121.Lstore16: 122 st.h r8[0], r12 123 bral .Lend 124 125.Lstore8: 126 st.b r8[0], r12 127 bral .Lend 128 129.Lend: 130 sub sp, -20 131 ldm sp++, r0,r1,pc 132 133 .size ffi_call_SYSV, . - ffi_call_SYSV 134 135 136 /* r12: __ctx 137 * r11: __rstruct_flag 138 * r10: __inner */ 139 140 .align 1 141 .globl ffi_closure_SYSV 142 .type ffi_closure_SYSV, @function 143ffi_closure_SYSV: 144 stm --sp, r0,lr 145 mov r0, r11 146 mov r8, r10 147 sub r10, sp, -8 148 sub sp, 12 149 st.w sp[8], sp 150 sub r11, sp, -8 151 icall r8 152 153 /* Check if return type is actually a struct */ 154 cp.w r0, 0 155 breq 1f 156 157 /* Return 8bit */ 158 cp.w r12, FFI_TYPE_UINT8 159 breq .Lget8 160 161 /* Return 16bit */ 162 cp.w r12, FFI_TYPE_UINT16 163 breq .Lget16 164 1651: 166 /* Return 32bit */ 167 cp.w r12, FFI_TYPE_UINT32 168 breq .Lget32 169 cp.w r12, FFI_TYPE_UINT16 170 breq .Lget32 171 cp.w r12, FFI_TYPE_UINT8 172 breq .Lget32 173 174 /* Return 64bit */ 175 cp.w r12, FFI_TYPE_UINT64 176 breq .Lget64 177 178 /* Didn't match anything */ 179 bral .Lclend 180 181.Lget64: 182 ld.w r11, sp[0] 183 ld.w r10, sp[4] 184 bral .Lclend 185 186.Lget32: 187 ld.w r12, sp[0] 188 bral .Lclend 189 190.Lget16: 191 ld.uh r12, sp[0] 192 bral .Lclend 193 194.Lget8: 195 ld.ub r12, sp[0] 196 bral .Lclend 197 198.Lclend: 199 sub sp, -12 200 ldm sp++, r0,lr 201 sub sp, -20 202 mov pc, lr 203 204 .size ffi_closure_SYSV, . - ffi_closure_SYSV 205 206#if defined __ELF__ && defined __linux__ 207 .section .note.GNU-stack,"",@progbits 208#endif 209