diff options
author | Vinay Sajip <vinay_sajip@yahoo.co.uk> | 2017-01-27 13:05:09 +0000 |
---|---|---|
committer | Vinay Sajip <vinay_sajip@yahoo.co.uk> | 2017-01-27 13:05:09 +0000 |
commit | d45d8652710e51576367db00b226b8465e6c5ce6 (patch) | |
tree | eeb12605abc98507852e82848382c2e739991708 /Modules/_ctypes/libffi/src/metag/sysv.S | |
parent | 6ccbbb38caa79f9eb9b93b5767f3787fc80cbac1 (diff) | |
parent | bbbab3c96168cea9f872f90da0a385b50f62ca70 (diff) | |
download | cpython-d45d8652710e51576367db00b226b8465e6c5ce6.tar.gz |
Closes #28784: Merged update from 3.6.
Diffstat (limited to 'Modules/_ctypes/libffi/src/metag/sysv.S')
-rw-r--r-- | Modules/_ctypes/libffi/src/metag/sysv.S | 311 |
1 files changed, 0 insertions, 311 deletions
diff --git a/Modules/_ctypes/libffi/src/metag/sysv.S b/Modules/_ctypes/libffi/src/metag/sysv.S deleted file mode 100644 index b4b2a3b26b..0000000000 --- a/Modules/_ctypes/libffi/src/metag/sysv.S +++ /dev/null @@ -1,311 +0,0 @@ -/* ----------------------------------------------------------------------- - sysv.S - Copyright (c) 2013 Imagination Technologies Ltd. - - Meta 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 THE AUTHORS OR COPYRIGHT - HOLDERS 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 -#ifdef __USER_LABEL_PREFIX__ -#define CONCAT1(a, b) CONCAT2(a, b) -#define CONCAT2(a, b) a ## b - -/* Use the right prefix for global labels. */ -#define CNAME(x) CONCAT1 (__USER_LABEL_PREFIX__, x) -#else -#define CNAME(x) x -#endif -#define ENTRY(x) .globl CNAME(x); .type CNAME(x), %function; CNAME(x): -#endif - -#ifdef __ELF__ -#define LSYM(x) .x -#else -#define LSYM(x) x -#endif - -.macro call_reg x= - .text - .balign 4 - mov D1RtP, \x - swap D1RtP, PC -.endm - -! Save register arguments -.macro SAVE_ARGS - .text - .balign 4 - setl [A0StP++], D0Ar6, D1Ar5 - setl [A0StP++], D0Ar4, D1Ar3 - setl [A0StP++], D0Ar2, D1Ar1 -.endm - -! Save retrun, frame pointer and other regs -.macro SAVE_REGS regs= - .text - .balign 4 - setl [A0StP++], D0FrT, D1RtP - ! Needs to be a pair of regs - .ifnc "\regs","" - setl [A0StP++], \regs - .endif -.endm - -! Declare a global function -.macro METAG_FUNC_START name - .text - .balign 4 - ENTRY(\name) -.endm - -! Return registers from the stack. Reverse SAVE_REGS operation -.macro RET_REGS regs=, cond= - .ifnc "\regs", "" - getl \regs, [--A0StP] - .endif - getl D0FrT, D1RtP, [--A0StP] -.endm - -! Return arguments -.macro RET_ARGS - getl D0Ar2, D1Ar1, [--A0StP] - getl D0Ar4, D1Ar3, [--A0StP] - getl D0Ar6, D1Ar5, [--A0StP] -.endm - - - ! D1Ar1: fn - ! D0Ar2: &ecif - ! D1Ar3: cif->bytes - ! D0Ar4: fig->flags - ! D1Ar5: ecif.rvalue - - ! This assumes we are using GNU as -METAG_FUNC_START ffi_call_SYSV - ! Save argument registers - - SAVE_ARGS - - ! new frame - mov D0FrT, A0FrP - add A0FrP, A0StP, #0 - - ! Preserve the old frame pointer - SAVE_REGS "D1.5, D0.5" - - ! Make room for new args. cifs->bytes is the total space for input - ! and return arguments - - add A0StP, A0StP, D1Ar3 - - ! Preserve cifs->bytes & fn - mov D0.5, D1Ar3 - mov D1.5, D1Ar1 - - ! Place all of the ffi_prep_args in position - mov D1Ar1, A0StP - - ! Call ffi_prep_args(stack, &ecif) -#ifdef __PIC__ - callr D1RtP, CNAME(ffi_prep_args@PLT) -#else - callr D1RtP, CNAME(ffi_prep_args) -#endif - - ! Restore fn pointer - - ! The foreign stack should look like this - ! XXXXX XXXXXX <--- stack pointer - ! FnArgN rvalue - ! FnArgN+2 FnArgN+1 - ! FnArgN+4 FnArgN+3 - ! .... - ! - - ! A0StP now points to the first (or return) argument + 4 - - ! Preserve cif->bytes - getl D0Ar2, D1Ar1, [--A0StP] - getl D0Ar4, D1Ar3, [--A0StP] - getl D0Ar6, D1Ar5, [--A0StP] - - ! Place A0StP to the first argument again - add A0StP, A0StP, #24 ! That's because we loaded 6 regs x 4 byte each - - ! A0FrP points to the initial stack without the reserved space for the - ! cifs->bytes, whilst A0StP points to the stack after the space allocation - - ! fn was the first argument of ffi_call_SYSV. - ! The stack at this point looks like this: - ! - ! A0StP(on entry to _SYSV) -> Arg6 Arg5 | low - ! Arg4 Arg3 | - ! Arg2 Arg1 | - ! A0FrP ----> D0FrtP D1RtP | - ! D1.5 D0.5 | - ! A0StP(bf prep_args) -> FnArgn FnArgn-1 | - ! FnArgn-2FnArgn-3 | - ! ................ | <= cifs->bytes - ! FnArg4 FnArg3 | - ! A0StP (prv_A0StP+cifs->bytes) FnArg2 FnArg1 | high - ! - ! fn was in Arg1 so it's located in in A0FrP+#-0xC - ! - - ! D0Re0 contains the size of arguments stored in registers - sub A0StP, A0StP, D0Re0 - - ! Arg1 is the function pointer for the foreign call. This has been - ! preserved in D1.5 - - ! Time to call (fn). Arguments should be like this: - ! Arg1-Arg6 are loaded to regs - ! The rest of the arguments are stored in stack pointed by A0StP - - call_reg D1.5 - - ! Reset stack. - - mov A0StP, A0FrP - - ! Load Arg1 with the pointer to storage for the return type - ! This was stored in Arg5 - - getd D1Ar1, [A0FrP+#-20] - - ! Load D0Ar2 with the return type code. This was stored in Arg4 (flags) - - getd D0Ar2, [A0FrP+#-16] - - ! We are ready to start processing the return value - ! D0Re0 (and D1Re0) hold the return value - - ! If the return value is NULL, assume no return value - cmp D1Ar1, #0 - beq LSYM(Lepilogue) - - ! return INT - cmp D0Ar2, #FFI_TYPE_INT - ! Sadly, there is no setd{cc} instruction so we need to workaround that - bne .INT64 - setd [D1Ar1], D0Re0 - b LSYM(Lepilogue) - - ! return INT64 -.INT64: - cmp D0Ar2, #FFI_TYPE_SINT64 - setleq [D1Ar1], D0Re0, D1Re0 - - ! return DOUBLE - cmp D0Ar2, #FFI_TYPE_DOUBLE - setl [D1AR1++], D0Re0, D1Re0 - -LSYM(Lepilogue): - ! At this point, the stack pointer points right after the argument - ! saved area. We need to restore 4 regs, therefore we need to move - ! 16 bytes ahead. - add A0StP, A0StP, #16 - RET_REGS "D1.5, D0.5" - RET_ARGS - getd D0Re0, [A0StP] - mov A0FrP, D0FrT - swap D1RtP, PC - -.ffi_call_SYSV_end: - .size CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV) - - -/* - (called by ffi_metag_trampoline) - void ffi_closure_SYSV (ffi_closure*) - - (called by ffi_closure_SYSV) - unsigned int FFI_HIDDEN - ffi_closure_SYSV_inner (closure,respp, args) - ffi_closure *closure; - void **respp; - void *args; -*/ - -METAG_FUNC_START ffi_closure_SYSV - ! We assume that D1Ar1 holds the address of the - ! ffi_closure struct. We will use that to fetch the - ! arguments. The stack pointer points to an empty space - ! and it is ready to store more data. - - ! D1Ar1 is ready - ! Allocate stack space for return value - add A0StP, A0StP, #8 - ! Store it to D0Ar2 - sub D0Ar2, A0StP, #8 - - sub D1Ar3, A0FrP, #4 - - ! D1Ar3 contains the address of the original D1Ar1 argument - ! We need to subtract #4 later on - - ! Preverve D0Ar2 - mov D0.5, D0Ar2 - -#ifdef __PIC__ - callr D1RtP, CNAME(ffi_closure_SYSV_inner@PLT) -#else - callr D1RtP, CNAME(ffi_closure_SYSV_inner) -#endif - - ! Check the return value and store it to D0.5 - cmp D0Re0, #FFI_TYPE_INT - beq .Lretint - cmp D0Re0, #FFI_TYPE_DOUBLE - beq .Lretdouble -.Lclosure_epilogue: - sub A0StP, A0StP, #8 - RET_REGS "D1.5, D0.5" - RET_ARGS - swap D1RtP, PC - -.Lretint: - setd [D0.5], D0Re0 - b .Lclosure_epilogue -.Lretdouble: - setl [D0.5++], D0Re0, D1Re0 - b .Lclosure_epilogue -.ffi_closure_SYSV_end: -.size CNAME(ffi_closure_SYSV),.ffi_closure_SYSV_end-CNAME(ffi_closure_SYSV) - - -ENTRY(ffi_metag_trampoline) - SAVE_ARGS - ! New frame - mov A0FrP, A0StP - SAVE_REGS "D1.5, D0.5" - mov D0.5, PC - ! Load D1Ar1 the value of ffi_metag_trampoline - getd D1Ar1, [D0.5 + #8] - ! Jump to ffi_closure_SYSV - getd PC, [D0.5 + #12] |