mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-01-19 21:05:04 +08:00
004-09-02 Andreas Tobler <a.tobler@schweiz.ch>
* src/powerpc/aix.S: Remove whitespaces. * src/powerpc/aix_closure.S: Likewise. * src/powerpc/asm.h: Likewise. * src/powerpc/ffi.c: Likewise. * src/powerpc/ffitarget.h: Likewise. * src/powerpc/linux64.S: Likewise. * src/powerpc/linux64_closure.S: Likewise. * src/powerpc/ppc_closure.S: Likewise. * src/powerpc/sysv.S: Likewise. From-SVN: r86991
This commit is contained in:
parent
19dc705e0c
commit
16070e459c
@ -1,3 +1,15 @@
|
||||
2004-09-02 Andreas Tobler <a.tobler@schweiz.ch>
|
||||
|
||||
* src/powerpc/aix.S: Remove whitespaces.
|
||||
* src/powerpc/aix_closure.S: Likewise.
|
||||
* src/powerpc/asm.h: Likewise.
|
||||
* src/powerpc/ffi.c: Likewise.
|
||||
* src/powerpc/ffitarget.h: Likewise.
|
||||
* src/powerpc/linux64.S: Likewise.
|
||||
* src/powerpc/linux64_closure.S: Likewise.
|
||||
* src/powerpc/ppc_closure.S: Likewise.
|
||||
* src/powerpc/sysv.S: Likewise.
|
||||
|
||||
2004-08-30 Anthony Green <green@redhat.com>
|
||||
|
||||
* Makefile.am: Add frv support.
|
||||
|
@ -24,62 +24,62 @@
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
.set r0,0
|
||||
.set r1,1
|
||||
.set r2,2
|
||||
.set r3,3
|
||||
.set r4,4
|
||||
.set r5,5
|
||||
.set r6,6
|
||||
.set r7,7
|
||||
.set r8,8
|
||||
.set r9,9
|
||||
.set r10,10
|
||||
.set r11,11
|
||||
.set r12,12
|
||||
.set r13,13
|
||||
.set r14,14
|
||||
.set r15,15
|
||||
.set r16,16
|
||||
.set r17,17
|
||||
.set r18,18
|
||||
.set r19,19
|
||||
.set r20,20
|
||||
.set r21,21
|
||||
.set r22,22
|
||||
.set r23,23
|
||||
.set r24,24
|
||||
.set r25,25
|
||||
.set r26,26
|
||||
.set r27,27
|
||||
.set r28,28
|
||||
.set r29,29
|
||||
.set r30,30
|
||||
.set r31,31
|
||||
.set f0,0
|
||||
.set f1,1
|
||||
.set f2,2
|
||||
.set f3,3
|
||||
.set f4,4
|
||||
.set f5,5
|
||||
.set f6,6
|
||||
.set f7,7
|
||||
.set f8,8
|
||||
.set f9,9
|
||||
.set f10,10
|
||||
.set f11,11
|
||||
.set f12,12
|
||||
.set f13,13
|
||||
.set f14,14
|
||||
.set f15,15
|
||||
.set f16,16
|
||||
.set f17,17
|
||||
.set f18,18
|
||||
.set f19,19
|
||||
.set f20,20
|
||||
.set f21,21
|
||||
.set r0,0
|
||||
.set r1,1
|
||||
.set r2,2
|
||||
.set r3,3
|
||||
.set r4,4
|
||||
.set r5,5
|
||||
.set r6,6
|
||||
.set r7,7
|
||||
.set r8,8
|
||||
.set r9,9
|
||||
.set r10,10
|
||||
.set r11,11
|
||||
.set r12,12
|
||||
.set r13,13
|
||||
.set r14,14
|
||||
.set r15,15
|
||||
.set r16,16
|
||||
.set r17,17
|
||||
.set r18,18
|
||||
.set r19,19
|
||||
.set r20,20
|
||||
.set r21,21
|
||||
.set r22,22
|
||||
.set r23,23
|
||||
.set r24,24
|
||||
.set r25,25
|
||||
.set r26,26
|
||||
.set r27,27
|
||||
.set r28,28
|
||||
.set r29,29
|
||||
.set r30,30
|
||||
.set r31,31
|
||||
.set f0,0
|
||||
.set f1,1
|
||||
.set f2,2
|
||||
.set f3,3
|
||||
.set f4,4
|
||||
.set f5,5
|
||||
.set f6,6
|
||||
.set f7,7
|
||||
.set f8,8
|
||||
.set f9,9
|
||||
.set f10,10
|
||||
.set f11,11
|
||||
.set f12,12
|
||||
.set f13,13
|
||||
.set f14,14
|
||||
.set f15,15
|
||||
.set f16,16
|
||||
.set f17,17
|
||||
.set f18,18
|
||||
.set f19,19
|
||||
.set f20,20
|
||||
.set f21,21
|
||||
|
||||
#define LIBFFI_ASM
|
||||
#define LIBFFI_ASM
|
||||
#include <fficonfig.h>
|
||||
#include <ffi.h>
|
||||
#define JUMPTARGET(name) name
|
||||
@ -104,7 +104,7 @@ ffi_call_AIX:
|
||||
mr r8,r1
|
||||
|
||||
/* Allocate the stack space we need. */
|
||||
stwux r1,r1,r4
|
||||
stwux r1,r1,r4
|
||||
|
||||
/* Save registers we use. */
|
||||
mflr r9
|
||||
@ -130,7 +130,7 @@ ffi_call_AIX:
|
||||
lwz r2,4(r12)
|
||||
lwz r12,0(r12)
|
||||
mtctr r12 // r12 holds address of _ffi_prep_args
|
||||
bctrl
|
||||
bctrl
|
||||
lwz r2,20(r1)
|
||||
|
||||
/* Now do the call. */
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
aix_closure.S - Copyright (c) 2002 2003 Free Software Foundation, Inc.
|
||||
based on darwin_closure.S
|
||||
based on darwin_closure.S
|
||||
|
||||
PowerPC Assembly glue.
|
||||
|
||||
@ -119,10 +119,10 @@ ffi_closure_ASM:
|
||||
in the parents outgoing area */
|
||||
stw r3, 200(r1)
|
||||
stw r4, 204(r1)
|
||||
stw r5, 208(r1)
|
||||
stw r5, 208(r1)
|
||||
stw r6, 212(r1)
|
||||
stw r7, 216(r1)
|
||||
stw r8, 220(r1)
|
||||
stw r8, 220(r1)
|
||||
stw r9, 224(r1)
|
||||
stw r10, 228(r1)
|
||||
|
||||
@ -135,11 +135,11 @@ ffi_closure_ASM:
|
||||
stfd f6, 96(r1)
|
||||
stfd f7, 104(r1)
|
||||
stfd f8, 112(r1)
|
||||
stfd f9, 120(r1)
|
||||
stfd f10, 128(r1)
|
||||
stfd f11, 136(r1)
|
||||
stfd f12, 144(r1)
|
||||
stfd f13, 152(r1)
|
||||
stfd f9, 120(r1)
|
||||
stfd f10, 128(r1)
|
||||
stfd f11, 136(r1)
|
||||
stfd f12, 144(r1)
|
||||
stfd f13, 152(r1)
|
||||
|
||||
/* set up registers for the routine that actually does the work */
|
||||
/* get the context pointer from the trampoline */
|
||||
@ -191,7 +191,7 @@ L..60:
|
||||
|
||||
|
||||
/* case double */
|
||||
L..46:
|
||||
L..46:
|
||||
lfd f1,0(r5)
|
||||
b L..44
|
||||
|
||||
@ -233,7 +233,7 @@ L..57:
|
||||
b L..44
|
||||
|
||||
/* case unsigned int16 */
|
||||
L..58:
|
||||
L..58:
|
||||
addi r5,r5,2
|
||||
lhz r3,0(r5)
|
||||
|
||||
|
@ -1,9 +1,7 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
asm.h - Copyright (c) 1998 Geoffrey Keating
|
||||
|
||||
PowerPC Assembly glue.
|
||||
|
||||
$Id: asm.h,v 1.1.1.1 1998/11/29 16:48:16 green Exp $
|
||||
PowerPC Assembly glue.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
@ -50,12 +48,12 @@
|
||||
#ifdef PIC
|
||||
#define CALL_MCOUNT \
|
||||
.pushsection; \
|
||||
.section ".data"; \
|
||||
.section ".data"; \
|
||||
.align ALIGNARG(2); \
|
||||
0:.long 0; \
|
||||
.previous; \
|
||||
mflr %r0; \
|
||||
stw %r0,4(%r1); \
|
||||
stw %r0,4(%r1); \
|
||||
bl _GLOBAL_OFFSET_TABLE_@local-4; \
|
||||
mflr %r11; \
|
||||
lwz %r0,0b@got(%r11); \
|
||||
@ -67,8 +65,8 @@
|
||||
0:.long 0; \
|
||||
.previous; \
|
||||
mflr %r0; \
|
||||
lis %r11,0b@ha; \
|
||||
stw %r0,4(%r1); \
|
||||
lis %r11,0b@ha; \
|
||||
stw %r0,4(%r1); \
|
||||
addi %r0,%r11,0b@l; \
|
||||
bl JUMPTARGET(_mcount);
|
||||
#endif /* PIC */
|
||||
@ -125,4 +123,3 @@
|
||||
|
||||
/* Local labels stripped out by the linker. */
|
||||
#define L(x) .L##x
|
||||
|
||||
|
@ -1,9 +1,7 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
ffi.c - Copyright (c) 1998 Geoffrey Keating
|
||||
|
||||
PowerPC Foreign Function Interface
|
||||
|
||||
$Id: ffi.c,v 1.1.1.1 1998/11/29 16:48:16 green Exp $
|
||||
PowerPC Foreign Function Interface
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
@ -67,7 +65,7 @@ enum { ASM_NEEDS_REGISTERS = 4 };
|
||||
|
||||
| Return address from ffi_call_SYSV 4bytes | higher addresses
|
||||
|--------------------------------------------|
|
||||
| Previous backchain pointer 4 | stack pointer here
|
||||
| Previous backchain pointer 4 | stack pointer here
|
||||
|--------------------------------------------|<+ <<< on entry to
|
||||
| Saved r28-r31 4*4 | | ffi_call_SYSV
|
||||
|--------------------------------------------| |
|
||||
@ -84,7 +82,7 @@ enum { ASM_NEEDS_REGISTERS = 4 };
|
||||
| Current backchain pointer 4 |-/ during
|
||||
|--------------------------------------------| <<< ffi_call_SYSV
|
||||
|
||||
*/
|
||||
*/
|
||||
|
||||
/*@-exportheader@*/
|
||||
void ffi_prep_args_SYSV(extended_cif *ecif, unsigned *const stack)
|
||||
@ -92,7 +90,7 @@ void ffi_prep_args_SYSV(extended_cif *ecif, unsigned *const stack)
|
||||
{
|
||||
const unsigned bytes = ecif->cif->bytes;
|
||||
const unsigned flags = ecif->cif->flags;
|
||||
|
||||
|
||||
/* 'stacktop' points at the previous backchain pointer. */
|
||||
unsigned *const stacktop = stack + (bytes / sizeof(unsigned));
|
||||
|
||||
@ -131,10 +129,10 @@ void ffi_prep_args_SYSV(extended_cif *ecif, unsigned *const stack)
|
||||
|
||||
/* Deal with return values that are actually pass-by-reference. */
|
||||
if (flags & FLAG_RETVAL_REFERENCE)
|
||||
{
|
||||
*gpr_base++ = (unsigned long)(char *)ecif->rvalue;
|
||||
intarg_count++;
|
||||
}
|
||||
{
|
||||
*gpr_base++ = (unsigned long)(char *)ecif->rvalue;
|
||||
intarg_count++;
|
||||
}
|
||||
|
||||
/* Now for the arguments. */
|
||||
p_argv = ecif->avalue;
|
||||
@ -192,18 +190,18 @@ void ffi_prep_args_SYSV(extended_cif *ecif, unsigned *const stack)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* whoops: abi states only certain register pairs
|
||||
* can be used for passing long long int
|
||||
* specifically (r3,r4), (r5,r6), (r7,r8),
|
||||
* (r9,r10) and if next arg is long long but
|
||||
* not correct starting register of pair then skip
|
||||
* until the proper starting register
|
||||
/* whoops: abi states only certain register pairs
|
||||
* can be used for passing long long int
|
||||
* specifically (r3,r4), (r5,r6), (r7,r8),
|
||||
* (r9,r10) and if next arg is long long but
|
||||
* not correct starting register of pair then skip
|
||||
* until the proper starting register
|
||||
*/
|
||||
if (intarg_count%2 != 0)
|
||||
{
|
||||
intarg_count ++;
|
||||
gpr_base++;
|
||||
}
|
||||
if (intarg_count%2 != 0)
|
||||
{
|
||||
intarg_count ++;
|
||||
gpr_base++;
|
||||
}
|
||||
*(long long *)gpr_base = *(long long *)*p_argv;
|
||||
gpr_base += 2;
|
||||
}
|
||||
@ -217,7 +215,7 @@ void ffi_prep_args_SYSV(extended_cif *ecif, unsigned *const stack)
|
||||
struct_copy_size = ((*ptr)->size + 15) & ~0xF;
|
||||
copy_space -= struct_copy_size;
|
||||
memcpy(copy_space, (char *)*p_argv, (*ptr)->size);
|
||||
|
||||
|
||||
gprvalue = (unsigned long)copy_space;
|
||||
|
||||
FFI_ASSERT(copy_space > (char *)next_arg);
|
||||
@ -276,7 +274,7 @@ enum { ASM_NEEDS_REGISTERS64 = 4 };
|
||||
|--------------------------------------------|
|
||||
| CR save area 8bytes |
|
||||
|--------------------------------------------|
|
||||
| Previous backchain pointer 8 | stack pointer here
|
||||
| Previous backchain pointer 8 | stack pointer here
|
||||
|--------------------------------------------|<+ <<< on entry to
|
||||
| Saved r28-r31 4*8 | | ffi_call_LINUX64
|
||||
|--------------------------------------------| |
|
||||
@ -299,7 +297,7 @@ enum { ASM_NEEDS_REGISTERS64 = 4 };
|
||||
| Current backchain pointer 8 |-/ during
|
||||
|--------------------------------------------| <<< ffi_call_LINUX64
|
||||
|
||||
*/
|
||||
*/
|
||||
|
||||
/*@-exportheader@*/
|
||||
void hidden ffi_prep_args64(extended_cif *ecif, unsigned long *const stack)
|
||||
@ -314,7 +312,7 @@ void hidden ffi_prep_args64(extended_cif *ecif, unsigned long *const stack)
|
||||
/* 'next_arg' points at the space for gpr3, and grows upwards as
|
||||
we use GPR registers, then continues at rest. */
|
||||
unsigned long *const gpr_base = stacktop - ASM_NEEDS_REGISTERS64
|
||||
- NUM_GPR_ARG_REGISTERS64;
|
||||
- NUM_GPR_ARG_REGISTERS64;
|
||||
unsigned long *const gpr_end = gpr_base + NUM_GPR_ARG_REGISTERS64;
|
||||
unsigned long *const rest = stack + 6 + NUM_GPR_ARG_REGISTERS64;
|
||||
unsigned long *next_arg = gpr_base;
|
||||
@ -434,7 +432,7 @@ void hidden ffi_prep_args64(extended_cif *ecif, unsigned long *const stack)
|
||||
case FFI_TYPE_SINT32:
|
||||
gprvalue = *(signed int *)*p_argv;
|
||||
goto putgpr;
|
||||
|
||||
|
||||
case FFI_TYPE_UINT64:
|
||||
case FFI_TYPE_SINT64:
|
||||
case FFI_TYPE_POINTER:
|
||||
@ -466,7 +464,7 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
|
||||
unsigned type = cif->rtype->type;
|
||||
|
||||
if (cif->abi != FFI_LINUX64)
|
||||
{
|
||||
{
|
||||
/* All the machine-independent calculation of cif->bytes will be wrong.
|
||||
Redo the calculation for SYSV. */
|
||||
|
||||
@ -497,10 +495,10 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
|
||||
- 32-bit (or less) integer values are returned in gpr3;
|
||||
- Structures of size <= 4 bytes also returned in gpr3;
|
||||
- 64-bit integer values and structures between 5 and 8 bytes are returned
|
||||
in gpr3 and gpr4;
|
||||
in gpr3 and gpr4;
|
||||
- Single/double FP values are returned in fpr1;
|
||||
- Larger structures and long double (if not equivalent to double) values
|
||||
are allocated space and a pointer is passed as the first argument.
|
||||
are allocated space and a pointer is passed as the first argument.
|
||||
For LINUX64:
|
||||
- integer values in gpr3;
|
||||
- Structures/Unions by reference;
|
||||
@ -674,31 +672,31 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
|
||||
|
||||
/*@-declundef@*/
|
||||
/*@-exportheader@*/
|
||||
extern void ffi_call_SYSV(/*@out@*/ extended_cif *,
|
||||
unsigned, unsigned,
|
||||
/*@out@*/ unsigned *,
|
||||
extern void ffi_call_SYSV(/*@out@*/ extended_cif *,
|
||||
unsigned, unsigned,
|
||||
/*@out@*/ unsigned *,
|
||||
void (*fn)());
|
||||
extern void hidden ffi_call_LINUX64(/*@out@*/ extended_cif *,
|
||||
extern void hidden ffi_call_LINUX64(/*@out@*/ extended_cif *,
|
||||
unsigned long, unsigned long,
|
||||
/*@out@*/ unsigned long *,
|
||||
/*@out@*/ unsigned long *,
|
||||
void (*fn)());
|
||||
/*@=declundef@*/
|
||||
/*@=exportheader@*/
|
||||
|
||||
void ffi_call(/*@dependent@*/ ffi_cif *cif,
|
||||
void (*fn)(),
|
||||
/*@out@*/ void *rvalue,
|
||||
void ffi_call(/*@dependent@*/ ffi_cif *cif,
|
||||
void (*fn)(),
|
||||
/*@out@*/ void *rvalue,
|
||||
/*@dependent@*/ void **avalue)
|
||||
{
|
||||
extended_cif ecif;
|
||||
|
||||
ecif.cif = cif;
|
||||
ecif.avalue = avalue;
|
||||
|
||||
|
||||
/* If the return value is a struct and we don't have a return */
|
||||
/* value address then we need to make one */
|
||||
|
||||
if ((rvalue == NULL) &&
|
||||
if ((rvalue == NULL) &&
|
||||
(cif->rtype->type == FFI_TYPE_STRUCT))
|
||||
{
|
||||
/*@-sysunrecog@*/
|
||||
@ -707,15 +705,15 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif,
|
||||
}
|
||||
else
|
||||
ecif.rvalue = rvalue;
|
||||
|
||||
|
||||
switch (cif->abi)
|
||||
|
||||
|
||||
switch (cif->abi)
|
||||
{
|
||||
#ifndef POWERPC64
|
||||
case FFI_SYSV:
|
||||
case FFI_GCC_SYSV:
|
||||
/*@-usedef@*/
|
||||
ffi_call_SYSV(&ecif, -cif->bytes,
|
||||
ffi_call_SYSV(&ecif, -cif->bytes,
|
||||
cif->flags, ecif.rvalue, fn);
|
||||
/*@=usedef@*/
|
||||
break;
|
||||
@ -744,8 +742,8 @@ static void flush_icache(char * addr1, int size)
|
||||
int i;
|
||||
char * addr;
|
||||
for (i = 0; i < size; i += MIN_CACHE_LINE_SIZE) {
|
||||
addr = addr1 + i;
|
||||
__asm__ volatile ("icbi 0,%0;" "dcbf 0,%0;" : : "r"(addr) : "memory");
|
||||
addr = addr1 + i;
|
||||
__asm__ volatile ("icbi 0,%0;" "dcbf 0,%0;" : : "r"(addr) : "memory");
|
||||
}
|
||||
addr = addr1 + size - 1;
|
||||
__asm__ volatile ("icbi 0,%0;" "dcbf 0,%0;" "sync;" "isync;" : : "r"(addr) : "memory");
|
||||
@ -799,21 +797,21 @@ typedef union
|
||||
double d;
|
||||
} ffi_dblfl;
|
||||
|
||||
int ffi_closure_helper_SYSV (ffi_closure*, void*, unsigned long*,
|
||||
int ffi_closure_helper_SYSV (ffi_closure*, void*, unsigned long*,
|
||||
ffi_dblfl*, unsigned long*);
|
||||
|
||||
/* Basically the trampoline invokes ffi_closure_SYSV, and on
|
||||
/* Basically the trampoline invokes ffi_closure_SYSV, and on
|
||||
* entry, r11 holds the address of the closure.
|
||||
* After storing the registers that could possibly contain
|
||||
* parameters to be passed into the stack frame and setting
|
||||
* up space for a return value, ffi_closure_SYSV invokes the
|
||||
* up space for a return value, ffi_closure_SYSV invokes the
|
||||
* following helper function to do most of the work
|
||||
*/
|
||||
|
||||
int
|
||||
ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue,
|
||||
unsigned long * pgr, ffi_dblfl * pfr,
|
||||
unsigned long * pst)
|
||||
ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue,
|
||||
unsigned long * pgr, ffi_dblfl * pfr,
|
||||
unsigned long * pst)
|
||||
{
|
||||
/* rvalue is the pointer to space for return value in closure assembly */
|
||||
/* pgr is the pointer to where r3-r10 are stored in ffi_closure_SYSV */
|
||||
@ -825,8 +823,8 @@ ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue,
|
||||
long i, avn;
|
||||
long nf; /* number of floating registers already used */
|
||||
long ng; /* number of general registers already used */
|
||||
ffi_cif * cif;
|
||||
double temp;
|
||||
ffi_cif * cif;
|
||||
double temp;
|
||||
|
||||
cif = closure->cif;
|
||||
avalue = alloca(cif->nargs * sizeof(void *));
|
||||
@ -846,7 +844,7 @@ ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue,
|
||||
i = 0;
|
||||
avn = cif->nargs;
|
||||
arg_types = cif->arg_types;
|
||||
|
||||
|
||||
/* Grab the addresses of the arguments from the stack frame. */
|
||||
while (i < avn)
|
||||
{
|
||||
@ -854,124 +852,124 @@ ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue,
|
||||
{
|
||||
case FFI_TYPE_SINT8:
|
||||
case FFI_TYPE_UINT8:
|
||||
/* there are 8 gpr registers used to pass values */
|
||||
if (ng < 8) {
|
||||
avalue[i] = (((char *)pgr)+3);
|
||||
ng++;
|
||||
pgr++;
|
||||
} else {
|
||||
avalue[i] = (((char *)pst)+3);
|
||||
pst++;
|
||||
}
|
||||
/* there are 8 gpr registers used to pass values */
|
||||
if (ng < 8) {
|
||||
avalue[i] = (((char *)pgr)+3);
|
||||
ng++;
|
||||
pgr++;
|
||||
} else {
|
||||
avalue[i] = (((char *)pst)+3);
|
||||
pst++;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case FFI_TYPE_SINT16:
|
||||
case FFI_TYPE_UINT16:
|
||||
/* there are 8 gpr registers used to pass values */
|
||||
if (ng < 8) {
|
||||
avalue[i] = (((char *)pgr)+2);
|
||||
ng++;
|
||||
pgr++;
|
||||
} else {
|
||||
avalue[i] = (((char *)pst)+2);
|
||||
pst++;
|
||||
}
|
||||
/* there are 8 gpr registers used to pass values */
|
||||
if (ng < 8) {
|
||||
avalue[i] = (((char *)pgr)+2);
|
||||
ng++;
|
||||
pgr++;
|
||||
} else {
|
||||
avalue[i] = (((char *)pst)+2);
|
||||
pst++;
|
||||
}
|
||||
break;
|
||||
|
||||
case FFI_TYPE_SINT32:
|
||||
case FFI_TYPE_UINT32:
|
||||
case FFI_TYPE_POINTER:
|
||||
/* there are 8 gpr registers used to pass values */
|
||||
if (ng < 8) {
|
||||
avalue[i] = pgr;
|
||||
ng++;
|
||||
pgr++;
|
||||
} else {
|
||||
avalue[i] = pst;
|
||||
pst++;
|
||||
}
|
||||
if (ng < 8) {
|
||||
avalue[i] = pgr;
|
||||
ng++;
|
||||
pgr++;
|
||||
} else {
|
||||
avalue[i] = pst;
|
||||
pst++;
|
||||
}
|
||||
break;
|
||||
|
||||
case FFI_TYPE_STRUCT:
|
||||
/* Structs are passed by reference. The address will appear in a
|
||||
/* Structs are passed by reference. The address will appear in a
|
||||
gpr if it is one of the first 8 arguments. */
|
||||
if (ng < 8) {
|
||||
avalue[i] = (void *) *pgr;
|
||||
ng++;
|
||||
pgr++;
|
||||
} else {
|
||||
avalue[i] = (void *) *pst;
|
||||
pst++;
|
||||
}
|
||||
if (ng < 8) {
|
||||
avalue[i] = (void *) *pgr;
|
||||
ng++;
|
||||
pgr++;
|
||||
} else {
|
||||
avalue[i] = (void *) *pst;
|
||||
pst++;
|
||||
}
|
||||
break;
|
||||
|
||||
case FFI_TYPE_SINT64:
|
||||
case FFI_TYPE_UINT64:
|
||||
/* passing long long ints are complex, they must
|
||||
* be passed in suitable register pairs such as
|
||||
* (r3,r4) or (r5,r6) or (r6,r7), or (r7,r8) or (r9,r10)
|
||||
* and if the entire pair aren't available then the outgoing
|
||||
* parameter stack is used for both but an alignment of 8
|
||||
* must will be kept. So we must either look in pgr
|
||||
* or pst to find the correct address for this type
|
||||
* of parameter.
|
||||
*/
|
||||
if (ng < 7) {
|
||||
if (ng & 0x01) {
|
||||
/* skip r4, r6, r8 as starting points */
|
||||
ng++;
|
||||
pgr++;
|
||||
}
|
||||
avalue[i] = pgr;
|
||||
ng+=2;
|
||||
pgr+=2;
|
||||
} else {
|
||||
if (((long)pst) & 4) pst++;
|
||||
avalue[i] = pst;
|
||||
pst+=2;
|
||||
}
|
||||
break;
|
||||
* be passed in suitable register pairs such as
|
||||
* (r3,r4) or (r5,r6) or (r6,r7), or (r7,r8) or (r9,r10)
|
||||
* and if the entire pair aren't available then the outgoing
|
||||
* parameter stack is used for both but an alignment of 8
|
||||
* must will be kept. So we must either look in pgr
|
||||
* or pst to find the correct address for this type
|
||||
* of parameter.
|
||||
*/
|
||||
if (ng < 7) {
|
||||
if (ng & 0x01) {
|
||||
/* skip r4, r6, r8 as starting points */
|
||||
ng++;
|
||||
pgr++;
|
||||
}
|
||||
avalue[i] = pgr;
|
||||
ng+=2;
|
||||
pgr+=2;
|
||||
} else {
|
||||
if (((long)pst) & 4) pst++;
|
||||
avalue[i] = pst;
|
||||
pst+=2;
|
||||
}
|
||||
break;
|
||||
|
||||
case FFI_TYPE_FLOAT:
|
||||
/* unfortunately float values are stored as doubles
|
||||
* in the ffi_closure_SYSV code (since we don't check
|
||||
* the type in that routine).
|
||||
*/
|
||||
/* unfortunately float values are stored as doubles
|
||||
* in the ffi_closure_SYSV code (since we don't check
|
||||
* the type in that routine).
|
||||
*/
|
||||
|
||||
/* there are 8 64bit floating point registers */
|
||||
/* there are 8 64bit floating point registers */
|
||||
|
||||
if (nf < 8) {
|
||||
temp = pfr->d;
|
||||
pfr->f = (float)temp;
|
||||
avalue[i] = pfr;
|
||||
nf++;
|
||||
pfr++;
|
||||
} else {
|
||||
if (nf < 8) {
|
||||
temp = pfr->d;
|
||||
pfr->f = (float)temp;
|
||||
avalue[i] = pfr;
|
||||
nf++;
|
||||
pfr++;
|
||||
} else {
|
||||
/* FIXME? here we are really changing the values
|
||||
* stored in the original calling routines outgoing
|
||||
* parameter stack. This is probably a really
|
||||
* naughty thing to do but...
|
||||
*/
|
||||
avalue[i] = pst;
|
||||
nf++;
|
||||
pst+=1;
|
||||
}
|
||||
* stored in the original calling routines outgoing
|
||||
* parameter stack. This is probably a really
|
||||
* naughty thing to do but...
|
||||
*/
|
||||
avalue[i] = pst;
|
||||
nf++;
|
||||
pst+=1;
|
||||
}
|
||||
break;
|
||||
|
||||
case FFI_TYPE_DOUBLE:
|
||||
/* On the outgoing stack all values are aligned to 8 */
|
||||
/* there are 8 64bit floating point registers */
|
||||
/* there are 8 64bit floating point registers */
|
||||
|
||||
if (nf < 8) {
|
||||
avalue[i] = pfr;
|
||||
nf++;
|
||||
pfr++;
|
||||
} else {
|
||||
if (((long)pst) & 4) pst++;
|
||||
avalue[i] = pst;
|
||||
nf++;
|
||||
pst+=2;
|
||||
}
|
||||
if (nf < 8) {
|
||||
avalue[i] = pfr;
|
||||
nf++;
|
||||
pfr++;
|
||||
} else {
|
||||
if (((long)pst) & 4) pst++;
|
||||
avalue[i] = pst;
|
||||
nf++;
|
||||
pst+=2;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -993,7 +991,7 @@ int hidden ffi_closure_helper_LINUX64 (ffi_closure*, void*, unsigned long*,
|
||||
ffi_dblfl*);
|
||||
|
||||
int hidden
|
||||
ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue,
|
||||
ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue,
|
||||
unsigned long *pst, ffi_dblfl *pfr)
|
||||
{
|
||||
/* rvalue is the pointer to space for return value in closure assembly */
|
||||
@ -1004,7 +1002,7 @@ ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue,
|
||||
void **avalue;
|
||||
ffi_type **arg_types;
|
||||
long i, avn;
|
||||
ffi_cif *cif;
|
||||
ffi_cif *cif;
|
||||
ffi_dblfl *end_pfr = pfr + NUM_FPR_ARG_REGISTERS64;
|
||||
|
||||
cif = closure->cif;
|
||||
@ -1021,7 +1019,7 @@ ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue,
|
||||
i = 0;
|
||||
avn = cif->nargs;
|
||||
arg_types = cif->arg_types;
|
||||
|
||||
|
||||
/* Grab the addresses of the arguments from the stack frame. */
|
||||
while (i < avn)
|
||||
{
|
||||
@ -1032,7 +1030,7 @@ ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue,
|
||||
avalue[i] = (char *) pst + 7;
|
||||
pst++;
|
||||
break;
|
||||
|
||||
|
||||
case FFI_TYPE_SINT16:
|
||||
case FFI_TYPE_UINT16:
|
||||
avalue[i] = (char *) pst + 6;
|
||||
@ -1064,13 +1062,13 @@ ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue,
|
||||
|
||||
case FFI_TYPE_FLOAT:
|
||||
/* unfortunately float values are stored as doubles
|
||||
* in the ffi_closure_LINUX64 code (since we don't check
|
||||
* the type in that routine).
|
||||
*/
|
||||
* in the ffi_closure_LINUX64 code (since we don't check
|
||||
* the type in that routine).
|
||||
*/
|
||||
|
||||
/* there are 13 64bit floating point registers */
|
||||
/* there are 13 64bit floating point registers */
|
||||
|
||||
if (pfr < end_pfr)
|
||||
if (pfr < end_pfr)
|
||||
{
|
||||
double temp = pfr->d;
|
||||
pfr->f = (float) temp;
|
||||
@ -1084,7 +1082,7 @@ ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue,
|
||||
|
||||
case FFI_TYPE_DOUBLE:
|
||||
/* On the outgoing stack all values are aligned to 8 */
|
||||
/* there are 13 64bit floating point registers */
|
||||
/* there are 13 64bit floating point registers */
|
||||
|
||||
if (pfr < end_pfr)
|
||||
{
|
||||
|
@ -88,4 +88,3 @@ struct ffi_aix_trampoline_struct {
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
sysv.h - Copyright (c) 2003 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
|
||||
PowerPC64 Assembly glue.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
@ -23,7 +23,7 @@
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#define LIBFFI_ASM
|
||||
#define LIBFFI_ASM
|
||||
#include <fficonfig.h>
|
||||
#include <ffi.h>
|
||||
|
||||
|
@ -5,15 +5,15 @@
|
||||
.file "linux64_closure.S"
|
||||
|
||||
#ifdef __powerpc64__
|
||||
.hidden ffi_closure_LINUX64, .ffi_closure_LINUX64
|
||||
.globl ffi_closure_LINUX64, .ffi_closure_LINUX64
|
||||
.section ".opd","aw"
|
||||
.align 3
|
||||
.hidden ffi_closure_LINUX64, .ffi_closure_LINUX64
|
||||
.globl ffi_closure_LINUX64, .ffi_closure_LINUX64
|
||||
.section ".opd","aw"
|
||||
.align 3
|
||||
ffi_closure_LINUX64:
|
||||
.quad .ffi_closure_LINUX64,.TOC.@tocbase,0
|
||||
.size ffi_closure_LINUX64,24
|
||||
.type .ffi_closure_LINUX64,@function
|
||||
.text
|
||||
.quad .ffi_closure_LINUX64,.TOC.@tocbase,0
|
||||
.size ffi_closure_LINUX64,24
|
||||
.type .ffi_closure_LINUX64,@function
|
||||
.text
|
||||
.ffi_closure_LINUX64:
|
||||
.LFB1:
|
||||
# save general regs into parm save area
|
||||
@ -71,7 +71,7 @@ ffi_closure_LINUX64:
|
||||
# so use it to look up in a table
|
||||
# so we know how to deal with each type
|
||||
|
||||
# look up the proper starting point in table
|
||||
# look up the proper starting point in table
|
||||
# by using return type as offset
|
||||
mflr %r4 # move address of .Lret to r4
|
||||
sldi %r3, %r3, 4 # now multiply return type by 16
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include <ffi.h>
|
||||
#include <powerpc/asm.h>
|
||||
|
||||
.file "ppc_closure.S"
|
||||
.file "ppc_closure.S"
|
||||
|
||||
#ifndef __powerpc64__
|
||||
|
||||
@ -17,14 +17,14 @@ ENTRY(ffi_closure_SYSV)
|
||||
|
||||
# we want to build up an areas for the parameters passed
|
||||
# in registers (both floating point and integer)
|
||||
|
||||
|
||||
# so first save gpr 3 to gpr 10 (aligned to 4)
|
||||
stw %r3, 16(%r1)
|
||||
stw %r4, 20(%r1)
|
||||
stw %r5, 24(%r1)
|
||||
stw %r5, 24(%r1)
|
||||
stw %r6, 28(%r1)
|
||||
stw %r7, 32(%r1)
|
||||
stw %r8, 36(%r1)
|
||||
stw %r8, 36(%r1)
|
||||
stw %r9, 40(%r1)
|
||||
stw %r10,44(%r1)
|
||||
|
||||
@ -41,29 +41,29 @@ ENTRY(ffi_closure_SYSV)
|
||||
# set up registers for the routine that actually does the work
|
||||
# get the context pointer from the trampoline
|
||||
mr %r3,%r11
|
||||
|
||||
# now load up the pointer to the result storage
|
||||
|
||||
# now load up the pointer to the result storage
|
||||
addi %r4,%r1,112
|
||||
|
||||
|
||||
# now load up the pointer to the saved gpr registers
|
||||
addi %r5,%r1,16
|
||||
addi %r5,%r1,16
|
||||
|
||||
# now load up the pointer to the saved fpr registers */
|
||||
addi %r6,%r1,48
|
||||
# now load up the pointer to the saved fpr registers */
|
||||
addi %r6,%r1,48
|
||||
|
||||
# now load up the pointer to the outgoing parameter
|
||||
# now load up the pointer to the outgoing parameter
|
||||
# stack in the previous frame
|
||||
# i.e. the previous frame pointer + 8
|
||||
addi %r7,%r1,152
|
||||
|
||||
# make the call
|
||||
|
||||
# make the call
|
||||
bl JUMPTARGET(ffi_closure_helper_SYSV)
|
||||
|
||||
# now r3 contains the return type
|
||||
# so use it to look up in a table
|
||||
# so we know how to deal with each type
|
||||
|
||||
# look up the proper starting point in table
|
||||
# look up the proper starting point in table
|
||||
# by using return type as offset
|
||||
addi %r5,%r1,112 # get pointer to results area
|
||||
bl .Lget_ret_type0_addr # get pointer to .Lret_type0 into LR
|
||||
@ -108,21 +108,21 @@ ENTRY(ffi_closure_SYSV)
|
||||
|
||||
# case FFI_TYPE_DOUBLE
|
||||
.Lret_type3:
|
||||
lfd %f1,0(%r5)
|
||||
lfd %f1,0(%r5)
|
||||
b .Lfinish
|
||||
nop
|
||||
nop
|
||||
|
||||
# case FFI_TYPE_LONGDOUBLE
|
||||
.Lret_type4:
|
||||
lfd %f1,0(%r5)
|
||||
lfd %f1,0(%r5)
|
||||
b .Lfinish
|
||||
nop
|
||||
nop
|
||||
|
||||
# case FFI_TYPE_UINT8
|
||||
.Lret_type5:
|
||||
lbz %r3,3(%r5)
|
||||
lbz %r3,3(%r5)
|
||||
b .Lfinish
|
||||
nop
|
||||
nop
|
||||
@ -190,9 +190,9 @@ ENTRY(ffi_closure_SYSV)
|
||||
nop
|
||||
nop
|
||||
|
||||
# case done
|
||||
# case done
|
||||
.Lfinish:
|
||||
|
||||
|
||||
lwz %r0,148(%r1)
|
||||
mtlr %r0
|
||||
addi %r1,%r1,144
|
||||
|
@ -1,9 +1,7 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
sysv.h - Copyright (c) 1998 Geoffrey Keating
|
||||
|
||||
PowerPC Assembly glue.
|
||||
|
||||
$Id: sysv.S,v 1.1.1.1 1998/11/29 16:48:16 green Exp $
|
||||
PowerPC Assembly glue.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
@ -25,7 +23,7 @@
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#define LIBFFI_ASM
|
||||
#define LIBFFI_ASM
|
||||
#include <fficonfig.h>
|
||||
#include <ffi.h>
|
||||
#include <powerpc/asm.h>
|
||||
|
Loading…
Reference in New Issue
Block a user