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