/* ----------------------------------------------------------------------- n32.S - Copyright (c) 1996, 1998 Cygnus Solutions MIPS Foreign Function Interface 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 CYGNUS SOLUTIONS 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 /* Only build this code if we are compiling for n32 */ #if defined(FFI_MIPS_N32) #define callback a0 #define bytes a2 #define flags a3 #define raddr a4 #define fn a5 #define SIZEOF_FRAME ( 8 * SIZEOF_ARG ) .text .align 2 .globl ffi_call_N32 .ent ffi_call_N32 ffi_call_N32: # Prologue SUBU $sp, SIZEOF_FRAME # Frame size REG_S $fp, SIZEOF_FRAME - 2*SIZEOF_ARG($sp) # Save frame pointer REG_S ra, SIZEOF_FRAME - 1*SIZEOF_ARG($sp) # Save return address move $fp, $sp move t9, callback # callback function pointer REG_S bytes, 2*SIZEOF_ARG($fp) # bytes REG_S flags, 3*SIZEOF_ARG($fp) # flags REG_S raddr, 4*SIZEOF_ARG($fp) # raddr REG_S fn, 5*SIZEOF_ARG($fp) # fn # Allocate at least 4 words in the argstack move v0, bytes bge bytes, 4 * SIZEOF_ARG, bigger LI v0, 4 * SIZEOF_ARG b sixteen bigger: ADDU t4, v0, 2 * SIZEOF_ARG -1 # make sure it is aligned and v0, t4, -2 * SIZEOF_ARG # to a proper boundry. sixteen: SUBU $sp, $sp, v0 # move the stack pointer to reflect the # arg space ADDU a0, $sp, 0 # 4 * SIZEOF_ARG ADDU a3, $fp, 3 * SIZEOF_ARG # Call ffi_prep_args jal t9 # ADDU $sp, $sp, 4 * SIZEOF_ARG # adjust $sp to new args # Copy the stack pointer to t9 move t9, $sp # Fix the stack if there are more than 8 64bit slots worth # of arguments. # Load the number of bytes REG_L t6, 2*SIZEOF_ARG($fp) # Is it bigger than 8 * SIZEOF_ARG? dadd t7, $0, 8 * SIZEOF_ARG dsub t8, t6, t7 bltz t8, loadregs add t9, t9, t8 loadregs: REG_L t4, 3*SIZEOF_ARG($fp) # load the flags word add t6, t4, 0 # and copy it into t6 and t4, ((1<