1 /* 2 * Copyright (c) 2013 Miodrag Vallat. <miod (at) openbsd.org> 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining 5 * a copy of this software and associated documentation files (the 6 * ``Software''), to deal in the Software without restriction, including 7 * without limitation the rights to use, copy, modify, merge, publish, 8 * distribute, sublicense, and/or sell copies of the Software, and to 9 * permit persons to whom the Software is furnished to do so, subject to 10 * the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be included 13 * in all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 */ 23 24 /* 25 * m88k Foreign Function Interface 26 */ 27 28 #define LIBFFI_ASM 29 #include <fficonfig.h> 30 #include <ffi.h> 31 32 .text 33 34 /* 35 * ffi_cacheflush_OBSD(unsigned int addr, %r2 36 * unsigned int size); %r3 37 */ 38 .align 4 39 .globl ffi_cacheflush_OBSD 40 .type ffi_cacheflush_OBSD,@function 41 ffi_cacheflush_OBSD: 42 tb0 0, %r0, 451 43 or %r0, %r0, %r0 44 jmp %r1 45 .size ffi_cacheflush_OBSD, . - ffi_cacheflush_OBSD 46 47 /* 48 * ffi_call_OBSD(unsigned bytes, %r2 49 * extended_cif *ecif, %r3 50 * unsigned flags, %r4 51 * void *rvalue, %r5 52 * void (*fn)()); %r6 53 */ 54 .align 4 55 .globl ffi_call_OBSD 56 .type ffi_call_OBSD,@function 57 ffi_call_OBSD: 58 subu %r31, %r31, 32 59 st %r30, %r31, 4 60 st %r1, %r31, 0 61 addu %r30, %r31, 32 62 63 | Save the few arguments we'll need after ffi_prep_args() 64 st.d %r4, %r31, 8 65 st %r6, %r31, 16 66 67 | Allocate room for the image of r2-r9, and the stack space for 68 | the args (rounded to a 16-byte boundary) 69 addu %r2, %r2, (8 * 4) + 15 70 clr %r2, %r2, 4<0> 71 subu %r31, %r31, %r2 72 73 | Fill register and stack image 74 or %r2, %r31, %r0 75 #ifdef PIC 76 bsr ffi_prep_args#plt 77 #else 78 bsr ffi_prep_args 79 #endif 80 81 | Save pointer to return struct address, if any 82 or %r12, %r2, %r0 83 84 | Get function pointer 85 subu %r4, %r30, 32 86 ld %r1, %r4, 16 87 88 | Fetch the register arguments 89 ld.d %r2, %r31, (0 * 4) 90 ld.d %r4, %r31, (2 * 4) 91 ld.d %r6, %r31, (4 * 4) 92 ld.d %r8, %r31, (6 * 4) 93 addu %r31, %r31, (8 * 4) 94 95 | Invoke the function 96 jsr %r1 97 98 | Restore stack now that we don't need the args anymore 99 subu %r31, %r30, 32 100 101 | Figure out what to return as the function's return value 102 ld %r5, %r31, 12 | rvalue 103 ld %r4, %r31, 8 | flags 104 105 bcnd eq0, %r5, 9f 106 107 bb0 0, %r4, 1f | CIF_FLAGS_INT 108 st %r2, %r5, 0 109 br 9f 110 111 1: 112 bb0 1, %r4, 1f | CIF_FLAGS_DINT 113 st.d %r2, %r5, 0 114 br 9f 115 116 1: 117 9: 118 ld %r1, %r31, 0 119 ld %r30, %r31, 4 120 jmp.n %r1 121 addu %r31, %r31, 32 122 .size ffi_call_OBSD, . - ffi_call_OBSD 123 124 /* 125 * ffi_closure_OBSD(ffi_closure *closure); %r13 126 */ 127 .align 4 128 .globl ffi_closure_OBSD 129 .type ffi_closure_OBSD, @function 130 ffi_closure_OBSD: 131 subu %r31, %r31, 16 132 st %r30, %r31, 4 133 st %r1, %r31, 0 134 addu %r30, %r31, 16 135 136 | Make room on the stack for saved register arguments and return 137 | value 138 subu %r31, %r31, (8 * 4) + (2 * 4) 139 st.d %r2, %r31, (0 * 4) 140 st.d %r4, %r31, (2 * 4) 141 st.d %r6, %r31, (4 * 4) 142 st.d %r8, %r31, (6 * 4) 143 144 | Invoke the closure function 145 or %r5, %r30, 0 | calling stack 146 addu %r4, %r31, 0 | saved registers 147 addu %r3, %r31, (8 * 4) | return value 148 or %r2, %r13, %r0 | closure 149 #ifdef PIC 150 bsr ffi_closure_OBSD_inner#plt 151 #else 152 bsr ffi_closure_OBSD_inner 153 #endif 154 155 | Figure out what to return as the function's return value 156 bb0 0, %r2, 1f | CIF_FLAGS_INT 157 ld %r2, %r31, (8 * 4) 158 br 9f 159 160 1: 161 bb0 1, %r2, 1f | CIF_FLAGS_DINT 162 ld.d %r2, %r31, (8 * 4) 163 br 9f 164 165 1: 166 9: 167 subu %r31, %r30, 16 168 ld %r1, %r31, 0 169 ld %r30, %r31, 4 170 jmp.n %r1 171 addu %r31, %r31, 16 172 .size ffi_closure_OBSD,.-ffi_closure_OBSD 173 174 /* 175 * ffi_closure_struct_OBSD(ffi_closure *closure); %r13 176 */ 177 .align 4 178 .globl ffi_closure_struct_OBSD 179 .type ffi_closure_struct_OBSD, @function 180 ffi_closure_struct_OBSD: 181 subu %r31, %r31, 16 182 st %r30, %r31, 4 183 st %r1, %r31, 0 184 addu %r30, %r31, 16 185 186 | Make room on the stack for saved register arguments 187 subu %r31, %r31, (8 * 4) 188 st.d %r2, %r31, (0 * 4) 189 st.d %r4, %r31, (2 * 4) 190 st.d %r6, %r31, (4 * 4) 191 st.d %r8, %r31, (6 * 4) 192 193 | Invoke the closure function 194 or %r5, %r30, 0 | calling stack 195 addu %r4, %r31, 0 | saved registers 196 or %r3, %r12, 0 | return value 197 or %r2, %r13, %r0 | closure 198 #ifdef PIC 199 bsr ffi_closure_OBSD_inner#plt 200 #else 201 bsr ffi_closure_OBSD_inner 202 #endif 203 204 subu %r31, %r30, 16 205 ld %r1, %r31, 0 206 ld %r30, %r31, 4 207 jmp.n %r1 208 addu %r31, %r31, 16 209 .size ffi_closure_struct_OBSD,.-ffi_closure_struct_OBSD 210