summaryrefslogtreecommitdiffstats
path: root/Modules/_ctypes/libffi/src/sh64
diff options
context:
space:
mode:
Diffstat (limited to 'Modules/_ctypes/libffi/src/sh64')
-rw-r--r--Modules/_ctypes/libffi/src/sh64/ffi.c59
-rw-r--r--Modules/_ctypes/libffi/src/sh64/sysv.S39
2 files changed, 63 insertions, 35 deletions
diff --git a/Modules/_ctypes/libffi/src/sh64/ffi.c b/Modules/_ctypes/libffi/src/sh64/ffi.c
index b17cf2c..8fbc05c 100644
--- a/Modules/_ctypes/libffi/src/sh64/ffi.c
+++ b/Modules/_ctypes/libffi/src/sh64/ffi.c
@@ -1,5 +1,5 @@
/* -----------------------------------------------------------------------
- ffi.c - Copyright (c) 2003, 2004 Kaz Kojima
+ ffi.c - Copyright (c) 2003, 2004, 2006, 2007 Kaz Kojima
Copyright (c) 2008 Anthony Green
SuperH SHmedia Foreign Function Interface
@@ -56,9 +56,7 @@ return_type (ffi_type *arg)
/* ffi_prep_args is called by the assembly routine once stack space
has been allocated for the function's arguments */
-/*@-exportheader@*/
void ffi_prep_args(char *stack, extended_cif *ecif)
-/*@=exportheader@*/
{
register unsigned int i;
register unsigned int avn;
@@ -162,6 +160,7 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
int n, m;
int greg;
int freg;
+ int fpair = -1;
greg = (return_type (cif->rtype) == FFI_TYPE_STRUCT ? 1 : 0);
freg = 0;
@@ -177,7 +176,13 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
cif->bytes += sizeof (UINT64) - sizeof (float);
if (freg >= NFREGARG - 1)
continue;
- freg++;
+ if (fpair < 0)
+ {
+ fpair = freg;
+ freg += 2;
+ }
+ else
+ fpair = -1;
cif->flags2 += ((cif->arg_types)[i]->type) << (2 * j++);
break;
@@ -186,7 +191,6 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
continue;
if ((freg + 1) < NFREGARG)
{
- freg = (freg + 1) & ~1;
freg += 2;
cif->flags2 += ((cif->arg_types)[i]->type) << (2 * j++);
}
@@ -264,9 +268,7 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif,
else if ((rvalue == NULL) &&
(cif->rtype->type == FFI_TYPE_STRUCT))
{
- /*@-sysunrecog@*/
ecif.rvalue = alloca(cif->rtype->size);
- /*@=sysunrecog@*/
}
else
ecif.rvalue = rvalue;
@@ -274,10 +276,8 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif,
switch (cif->abi)
{
case FFI_SYSV:
- /*@-usedef@*/
- ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes,
- cif->flags, cif->flags2, ecif.rvalue, fn);
- /*@=usedef@*/
+ ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, cif->flags2,
+ ecif.rvalue, fn);
break;
default:
FFI_ASSERT(0);
@@ -294,10 +294,11 @@ extern void ffi_closure_SYSV (void);
extern void __ic_invalidate (void *line);
ffi_status
-ffi_prep_closure (ffi_closure *closure,
- ffi_cif *cif,
- void (*fun)(ffi_cif*, void*, void**, void*),
- void *user_data)
+ffi_prep_closure_loc (ffi_closure *closure,
+ ffi_cif *cif,
+ void (*fun)(ffi_cif*, void*, void**, void*),
+ void *user_data,
+ void *codeloc)
{
unsigned int *tramp;
@@ -321,8 +322,8 @@ ffi_prep_closure (ffi_closure *closure,
tramp[2] = 0xcc000010 | (((UINT32) ffi_closure_SYSV) >> 16) << 10;
tramp[3] = 0xc8000010 | (((UINT32) ffi_closure_SYSV) & 0xffff) << 10;
tramp[4] = 0x6bf10600;
- tramp[5] = 0xcc000010 | (((UINT32) closure) >> 16) << 10;
- tramp[6] = 0xc8000010 | (((UINT32) closure) & 0xffff) << 10;
+ tramp[5] = 0xcc000010 | (((UINT32) codeloc) >> 16) << 10;
+ tramp[6] = 0xc8000010 | (((UINT32) codeloc) & 0xffff) << 10;
tramp[7] = 0x4401fff0;
closure->cif = cif;
@@ -330,7 +331,8 @@ ffi_prep_closure (ffi_closure *closure,
closure->user_data = user_data;
/* Flush the icache. */
- asm volatile ("ocbwb %0,0; synco; icbi %0,0; synci" : : "r" (tramp));
+ asm volatile ("ocbwb %0,0; synco; icbi %1,0; synci" : : "r" (tramp),
+ "r"(codeloc));
return FFI_OK;
}
@@ -352,6 +354,7 @@ ffi_closure_helper_SYSV (ffi_closure *closure, UINT64 *rvalue,
int i, avn;
int greg, freg;
ffi_cif *cif;
+ int fpair = -1;
cif = closure->cif;
avalue = alloca (cif->nargs * sizeof (void *));
@@ -360,7 +363,7 @@ ffi_closure_helper_SYSV (ffi_closure *closure, UINT64 *rvalue,
returns the data directly to the caller. */
if (return_type (cif->rtype) == FFI_TYPE_STRUCT)
{
- rvalue = *pgr;
+ rvalue = (UINT64 *) *pgr;
greg = 1;
}
else
@@ -404,11 +407,24 @@ ffi_closure_helper_SYSV (ffi_closure *closure, UINT64 *rvalue,
if ((*p_arg)->type == FFI_TYPE_FLOAT)
{
if (freg < NFREGARG - 1)
+ {
+ if (fpair >= 0)
+ {
+ avalue[i] = (UINT32 *) pfr + fpair;
+ fpair = -1;
+ }
+ else
+ {
#ifdef __LITTLE_ENDIAN__
- avalue[i] = (UINT32 *) pfr + (1 ^ freg++);
+ fpair = freg;
+ avalue[i] = (UINT32 *) pfr + (1 ^ freg);
#else
- avalue[i] = (UINT32 *) pfr + freg++;
+ fpair = 1 ^ freg;
+ avalue[i] = (UINT32 *) pfr + freg;
#endif
+ freg += 2;
+ }
+ }
else
#ifdef __LITTLE_ENDIAN__
avalue[i] = pgr + greg;
@@ -430,7 +446,6 @@ ffi_closure_helper_SYSV (ffi_closure *closure, UINT64 *rvalue,
avalue[i] = pgr + greg;
else
{
- freg = (freg + 1) & ~1;
avalue[i] = pfr + (freg >> 1);
freg += 2;
}
diff --git a/Modules/_ctypes/libffi/src/sh64/sysv.S b/Modules/_ctypes/libffi/src/sh64/sysv.S
index b6a248d..c4587d5 100644
--- a/Modules/_ctypes/libffi/src/sh64/sysv.S
+++ b/Modules/_ctypes/libffi/src/sh64/sysv.S
@@ -1,5 +1,5 @@
/* -----------------------------------------------------------------------
- sysv.S - Copyright (c) 2003, 2004 Kaz Kojima
+ sysv.S - Copyright (c) 2003, 2004, 2006, 2008 Kaz Kojima
SuperH SHmedia Foreign Function Interface
@@ -14,14 +14,15 @@
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.
+
+ 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
@@ -85,6 +86,7 @@ ENTRY(ffi_call_SYSV)
addi r15, 64, r22
movi 0, r0
movi 0, r1
+ movi -1, r23
pt/l 1f, tr1
bnei/l r29, FFI_TYPE_STRUCT, tr1
@@ -107,9 +109,6 @@ ENTRY(ffi_call_SYSV)
.L_pass_d:
addi r0, 1, r0
- addi r1, 1, r1
- andi r1, ~1, r1
-
pt/l 3f, tr0
movi 12, r20
bge/l r1, r20, tr0
@@ -159,13 +158,23 @@ ENTRY(ffi_call_SYSV)
addi.l r15, 8, r15
3:
pt/l .L_pass, tr0
- addi r1, 1, r1
blink tr0, r63
.L_pop_f:
pt/l .L_pop_f_tbl, tr1
+ pt/l 5f, tr2
gettr tr1, r20
+ bge/l r23, r63, tr2
+ add r1, r63, r23
shlli r1, 3, r21
+ addi r1, 2, r1
+ add r20, r21, r20
+ ptabs/l r20, tr1
+ blink tr1, r63
+5:
+ addi r23, 1, r21
+ movi -1, r23
+ shlli r21, 3, r21
add r20, r21, r20
ptabs/l r20, tr1
blink tr1, r63
@@ -430,6 +439,10 @@ ENTRY(ffi_closure_SYSV)
.ffi_closure_SYSV_end:
.size CNAME(ffi_closure_SYSV),.ffi_closure_SYSV_end-CNAME(ffi_closure_SYSV)
+#if defined __ELF__ && defined __linux__
+ .section .note.GNU-stack,"",@progbits
+#endif
+
.section ".eh_frame","aw",@progbits
__FRAME_BEGIN__:
.4byte .LECIE1-.LSCIE1 /* Length of Common Information Entry */