/Modules/_ctypes/libffi/src/m32r/sysv.S
http://unladen-swallow.googlecode.com/ · Assembly · 121 lines · 57 code · 18 blank · 46 comment · 0 complexity · fde1f5cb81ab7ce114af861c94c368c0 MD5 · raw file
- /* -----------------------------------------------------------------------
- sysv.S - Copyright (c) 2004 Renesas Technology
-
- M32R 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 RENESAS TECHNOLOGY 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>
- #ifdef HAVE_MACHINE_ASM_H
- #include <machine/asm.h>
- #else
- /* XXX these lose for some platforms, I'm sure. */
- #define CNAME(x) x
- #define ENTRY(x) .globl CNAME(x)! .type CNAME(x),%function! CNAME(x):
- #endif
- .text
- /* R0: ffi_prep_args */
- /* R1: &ecif */
- /* R2: cif->bytes */
- /* R3: fig->flags */
- /* sp+0: ecif.rvalue */
- /* sp+4: fn */
- /* This assumes we are using gas. */
- ENTRY(ffi_call_SYSV)
- /* Save registers. */
- push fp
- push lr
- push r3
- push r2
- push r1
- push r0
- mv fp, sp
- /* Make room for all of the new args. */
- sub sp, r2
- /* Place all of the ffi_prep_args in position. */
- mv lr, r0
- mv r0, sp
- /* R1 already set. */
- /* And call. */
- jl lr
- /* Move first 4 parameters in registers... */
- ld r0, @(0,sp)
- ld r1, @(4,sp)
- ld r2, @(8,sp)
- ld r3, @(12,sp)
- /* ...and adjust the stack. */
- ld lr, @(8,fp)
- cmpi lr, #16
- bc adjust_stack
- ldi lr, #16
- adjust_stack:
- add sp, lr
- /* Call the function. */
- ld lr, @(28,fp)
- jl lr
- /* Remove the space we pushed for the args. */
- mv sp, fp
- /* Load R2 with the pointer to storage for the return value. */
- ld r2, @(24,sp)
- /* Load R3 with the return type code. */
- ld r3, @(12,sp)
- /* If the return value pointer is NULL, assume no return value. */
- beqz r2, epilogue
- /* Return INT. */
- ldi r4, #FFI_TYPE_INT
- bne r3, r4, return_double
- st r0, @r2
- bra epilogue
- return_double:
- /* Return DOUBLE or LONGDOUBLE. */
- ldi r4, #FFI_TYPE_DOUBLE
- bne r3, r4, epilogue
- st r0, @r2
- st r1, @(4,r2)
- epilogue:
- pop r0
- pop r1
- pop r2
- pop r3
- pop lr
- pop fp
- jmp lr
- .ffi_call_SYSV_end:
- .size CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV)