Latest gcc svn sources

This commit is contained in:
green
2008-01-29 15:15:20 +00:00
parent 2544e45a0b
commit 77175b3f72
141 changed files with 5242 additions and 2218 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,11 +1,12 @@
/* -----------------------------------------------------------------------
ffi.c - Copyright (c) 1998 Geoffrey Keating
ffi_darwin.c
PowerPC Foreign Function Interface
Darwin ABI support (c) 2001 John Hornkvist
AIX ABI support (c) 2002 Free Software Foundation, Inc.
Copyright (C) 1998 Geoffrey Keating
Copyright (C) 2001 John Hornkvist
Copyright (C) 2002, 2006, 2007 Free Software Foundation, Inc.
FFI support for Darwin and AIX.
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
@@ -79,9 +80,7 @@ enum { ASM_NEEDS_REGISTERS = 4 };
*/
/*@-exportheader@*/
void ffi_prep_args(extended_cif *ecif, unsigned *const stack)
/*@=exportheader@*/
{
const unsigned bytes = ecif->cif->bytes;
const unsigned flags = ecif->cif->flags;
@@ -227,6 +226,48 @@ void ffi_prep_args(extended_cif *ecif, unsigned *const stack)
//FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);
}
/* Adjust the size of S to be correct for Darwin.
On Darwin, the first field of a structure has natural alignment. */
static void
darwin_adjust_aggregate_sizes (ffi_type *s)
{
int i;
if (s->type != FFI_TYPE_STRUCT)
return;
s->size = 0;
for (i = 0; s->elements[i] != NULL; i++)
{
ffi_type *p;
int align;
p = s->elements[i];
darwin_adjust_aggregate_sizes (p);
if (i == 0
&& (p->type == FFI_TYPE_UINT64
|| p->type == FFI_TYPE_SINT64
|| p->type == FFI_TYPE_DOUBLE
|| p->alignment == 8))
align = 8;
else if (p->alignment == 16 || p->alignment < 4)
align = p->alignment;
else
align = 4;
s->size = ALIGN(s->size, align) + p->size;
}
s->size = ALIGN(s->size, s->alignment);
if (s->elements[0]->type == FFI_TYPE_UINT64
|| s->elements[0]->type == FFI_TYPE_SINT64
|| s->elements[0]->type == FFI_TYPE_DOUBLE
|| s->elements[0]->alignment == 8)
s->alignment = s->alignment > 8 ? s->alignment : 8;
/* Do not add additional tail padding. */
}
/* Perform machine dependent cif processing. */
ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
{
@@ -239,8 +280,16 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
unsigned size_al = 0;
/* All the machine-independent calculation of cif->bytes will be wrong.
All the calculation of structure sizes will also be wrong.
Redo the calculation for DARWIN. */
if (cif->abi == FFI_DARWIN)
{
darwin_adjust_aggregate_sizes (cif->rtype);
for (i = 0; i < cif->nargs; i++)
darwin_adjust_aggregate_sizes (cif->arg_types[i]);
}
/* Space for the frame pointer, callee's LR, CR, etc, and for
the asm's temp regs. */
@@ -375,25 +424,12 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
return FFI_OK;
}
/*@-declundef@*/
/*@-exportheader@*/
extern void ffi_call_AIX(/*@out@*/ extended_cif *,
unsigned, unsigned,
/*@out@*/ unsigned *,
void (*fn)(),
void (*fn2)());
extern void ffi_call_DARWIN(/*@out@*/ extended_cif *,
unsigned, unsigned,
/*@out@*/ unsigned *,
void (*fn)(),
void (*fn2)());
/*@=declundef@*/
/*@=exportheader@*/
extern void ffi_call_AIX(extended_cif *, unsigned, unsigned, unsigned *,
void (*fn)(), void (*fn2)());
extern void ffi_call_DARWIN(extended_cif *, unsigned, unsigned, unsigned *,
void (*fn)(), void (*fn2)());
void ffi_call(/*@dependent@*/ ffi_cif *cif,
void (*fn)(),
/*@out@*/ void *rvalue,
/*@dependent@*/ void **avalue)
void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
{
extended_cif ecif;
@@ -406,9 +442,7 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif,
if ((rvalue == NULL) &&
(cif->rtype->type == FFI_TYPE_STRUCT))
{
/*@-sysunrecog@*/
ecif.rvalue = alloca(cif->rtype->size);
/*@=sysunrecog@*/
}
else
ecif.rvalue = rvalue;
@@ -416,16 +450,12 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif,
switch (cif->abi)
{
case FFI_AIX:
/*@-usedef@*/
ffi_call_AIX(&ecif, -cif->bytes,
cif->flags, ecif.rvalue, fn, ffi_prep_args);
/*@=usedef@*/
ffi_call_AIX(&ecif, -cif->bytes, cif->flags, ecif.rvalue, fn,
ffi_prep_args);
break;
case FFI_DARWIN:
/*@-usedef@*/
ffi_call_DARWIN(&ecif, -cif->bytes,
cif->flags, ecif.rvalue, fn, ffi_prep_args);
/*@=usedef@*/
ffi_call_DARWIN(&ecif, -cif->bytes, cif->flags, ecif.rvalue, fn,
ffi_prep_args);
break;
default:
FFI_ASSERT(0);
@@ -498,10 +528,11 @@ SP current --> +---------------------------------------+ 176 <- parent frame
*/
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;
struct ffi_aix_trampoline_struct *tramp_aix;
@@ -523,14 +554,14 @@ ffi_prep_closure (ffi_closure* closure,
tramp[8] = 0x816b0004; /* lwz r11,4(r11) static chain */
tramp[9] = 0x4e800420; /* bctr */
tramp[2] = (unsigned long) ffi_closure_ASM; /* function */
tramp[3] = (unsigned long) closure; /* context */
tramp[3] = (unsigned long) codeloc; /* context */
closure->cif = cif;
closure->fun = fun;
closure->user_data = user_data;
/* Flush the icache. Only necessary on Darwin. */
flush_range(&closure->tramp[0],FFI_TRAMPOLINE_SIZE);
flush_range(codeloc, FFI_TRAMPOLINE_SIZE);
break;
@@ -543,7 +574,7 @@ ffi_prep_closure (ffi_closure* closure,
tramp_aix->code_pointer = fd->code_pointer;
tramp_aix->toc = fd->toc;
tramp_aix->static_chain = closure;
tramp_aix->static_chain = codeloc;
closure->cif = cif;
closure->fun = fun;
closure->user_data = user_data;

View File

@@ -1,5 +1,6 @@
/* -----------------------------------------------------------------*-C-*-
ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc.
Copyright (C) 2007 Free Software Foundation, Inc
Target configuration macros for PowerPC.
Permission is hereby granted, free of charge, to any person obtaining
@@ -43,10 +44,20 @@ typedef enum ffi_abi {
FFI_SYSV,
FFI_GCC_SYSV,
FFI_LINUX64,
FFI_LINUX,
FFI_LINUX_SOFT_FLOAT,
# ifdef POWERPC64
FFI_DEFAULT_ABI = FFI_LINUX64,
# else
# if (!defined(__NO_FPRS__) && (__LDBL_MANT_DIG__ == 106))
FFI_DEFAULT_ABI = FFI_LINUX,
# else
# ifdef __NO_FPRS__
FFI_DEFAULT_ABI = FFI_LINUX_SOFT_FLOAT,
# else
FFI_DEFAULT_ABI = FFI_GCC_SYSV,
# endif
# endif
# endif
#endif
@@ -69,7 +80,7 @@ typedef enum ffi_abi {
FFI_DEFAULT_ABI = FFI_SYSV,
#endif
FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
FFI_LAST_ABI
} ffi_abi;
#endif
@@ -78,8 +89,14 @@ typedef enum ffi_abi {
#define FFI_CLOSURES 1
#define FFI_NATIVE_RAW_API 0
/* For additional types like the below, take care about the order in
ppc_closures.S. They must follow after the FFI_TYPE_LAST. */
/* Needed for soft-float long-double-128 support. */
#define FFI_TYPE_UINT128 (FFI_TYPE_LAST + 1)
/* Needed for FFI_SYSV small structure returns. */
#define FFI_SYSV_TYPE_SMALL_STRUCT (FFI_TYPE_LAST)
#define FFI_SYSV_TYPE_SMALL_STRUCT (FFI_TYPE_LAST + 2)
#if defined(POWERPC64) || defined(POWERPC_AIX)
#define FFI_TRAMPOLINE_SIZE 24

View File

@@ -47,8 +47,8 @@ ffi_call_LINUX64:
std %r0, 16(%r1)
mr %r28, %r1 /* our AP. */
stdux %r1, %r1, %r4
.LCFI0:
stdux %r1, %r1, %r4
mr %r31, %r5 /* flags, */
mr %r30, %r6 /* rvalue, */
mr %r29, %r7 /* function address. */
@@ -100,6 +100,10 @@ ffi_call_LINUX64:
/* Make the call. */
bctrl
/* This must follow the call immediately, the unwinder
uses this to find out if r2 has been saved or not. */
ld %r2, 40(%r1)
/* Now, deal with the return value. */
mtcrf 0x01, %r31
bt- 30, .Ldone_return_value
@@ -109,7 +113,6 @@ ffi_call_LINUX64:
.Ldone_return_value:
/* Restore the registers we used and return. */
ld %r2, 40(%r1)
mr %r1, %r28
ld %r0, 16(%r28)
ld %r28, -32(%r1)
@@ -120,12 +123,10 @@ ffi_call_LINUX64:
blr
.Lfp_return_value:
bt 27, .Lfd_return_value
bf 28, .Lfloat_return_value
stfd %f1, 0(%r30)
b .Ldone_return_value
.Lfd_return_value:
stfd %f1, 0(%r30)
mtcrf 0x02, %r31 /* cr6 */
bf 27, .Ldone_return_value
stfd %f2, 8(%r30)
b .Ldone_return_value
.Lfloat_return_value:

View File

@@ -28,6 +28,7 @@ ENTRY(ffi_closure_SYSV)
stw %r9, 40(%r1)
stw %r10,44(%r1)
#ifndef __NO_FPRS__
# next save fpr 1 to fpr 8 (aligned to 8)
stfd %f1, 48(%r1)
stfd %f2, 56(%r1)
@@ -37,6 +38,7 @@ ENTRY(ffi_closure_SYSV)
stfd %f6, 88(%r1)
stfd %f7, 96(%r1)
stfd %f8, 104(%r1)
#endif
# set up registers for the routine that actually does the work
# get the context pointer from the trampoline
@@ -58,223 +60,190 @@ ENTRY(ffi_closure_SYSV)
# make the call
bl ffi_closure_helper_SYSV@local
.Lret:
# now r3 contains the return type
# so use it to look up in a table
# so we know how to deal with each type
# Extract the size of the return type for small structures.
# Then calculate (4 - size) and multiply the result by 8.
# This gives the value needed for the shift operation below.
# This part is only needed for FFI_SYSV and small structures.
addi %r5,%r3,-(FFI_SYSV_TYPE_SMALL_STRUCT)
cmpwi cr0,%r5,4
ble cr0,.Lnext
addi %r5,%r5,-4
.Lnext:
addi %r5,%r5,-4
neg %r5,%r5
slwi %r5,%r5,3
# look up the proper starting point in table
# by using return type as offset
addi %r6,%r1,112 # get pointer to results area
bl .Lget_ret_type0_addr # get pointer to .Lret_type0 into LR
mflr %r4 # move to r4
slwi %r3,%r3,4 # now multiply return type by 16
add %r3,%r3,%r4 # add contents of table to table address
mflr %r4 # move address of .Lret to r4
slwi %r3,%r3,4 # now multiply return type by 16
addi %r4, %r4, .Lret_type0 - .Lret
lwz %r0,148(%r1)
add %r3,%r3,%r4 # add contents of table to table address
mtctr %r3
bctr # jump to it
bctr # jump to it
.LFE1:
# Each of the ret_typeX code fragments has to be exactly 16 bytes long
# (4 instructions). For cache effectiveness we align to a 16 byte boundary
# first.
.align 4
nop
nop
nop
.Lget_ret_type0_addr:
blrl
# case FFI_TYPE_VOID
.Lret_type0:
b .Lfinish
nop
nop
nop
# case FFI_TYPE_INT
.Lret_type1:
lwz %r3,0(%r6)
b .Lfinish
nop
nop
# case FFI_TYPE_FLOAT
.Lret_type2:
lfs %f1,0(%r6)
b .Lfinish
nop
nop
# case FFI_TYPE_DOUBLE
.Lret_type3:
lfd %f1,0(%r6)
b .Lfinish
nop
nop
# case FFI_TYPE_LONGDOUBLE
.Lret_type4:
lfd %f1,0(%r6)
b .Lfinish
nop
nop
# case FFI_TYPE_UINT8
.Lret_type5:
lbz %r3,3(%r6)
b .Lfinish
nop
nop
# case FFI_TYPE_SINT8
.Lret_type6:
lbz %r3,3(%r6)
extsb %r3,%r3
b .Lfinish
nop
# case FFI_TYPE_UINT16
.Lret_type7:
lhz %r3,2(%r6)
b .Lfinish
nop
nop
# case FFI_TYPE_SINT16
.Lret_type8:
lha %r3,2(%r6)
b .Lfinish
nop
nop
# case FFI_TYPE_UINT32
.Lret_type9:
lwz %r3,0(%r6)
b .Lfinish
nop
nop
# case FFI_TYPE_SINT32
.Lret_type10:
lwz %r3,0(%r6)
b .Lfinish
nop
nop
# case FFI_TYPE_UINT64
.Lret_type11:
lwz %r3,0(%r6)
lwz %r4,4(%r6)
b .Lfinish
nop
# case FFI_TYPE_SINT64
.Lret_type12:
lwz %r3,0(%r6)
lwz %r4,4(%r6)
b .Lfinish
nop
# case FFI_TYPE_STRUCT
.Lret_type13:
b .Lfinish
nop
nop
nop
# case FFI_TYPE_POINTER
.Lret_type14:
lwz %r3,0(%r6)
b .Lfinish
nop
nop
# The return types below are only used when the ABI type is FFI_SYSV.
# case FFI_SYSV_TYPE_SMALL_STRUCT + 1. One byte struct.
.Lret_type15:
# fall through.
nop
nop
nop
nop
# case FFI_SYSV_TYPE_SMALL_STRUCT + 2. Two byte struct.
.Lret_type16:
# fall through.
nop
nop
nop
nop
# case FFI_SYSV_TYPE_SMALL_STRUCT + 3. Three byte struct.
.Lret_type17:
# fall through.
nop
nop
nop
nop
# case FFI_SYSV_TYPE_SMALL_STRUCT + 4. Four byte struct.
.Lret_type18:
# this one handles the structs from above too.
lwz %r3,0(%r6)
srw %r3,%r3,%r5
b .Lfinish
nop
# case FFI_SYSV_TYPE_SMALL_STRUCT + 5. Five byte struct.
.Lret_type19:
# fall through.
nop
nop
nop
nop
# case FFI_SYSV_TYPE_SMALL_STRUCT + 6. Six byte struct.
.Lret_type20:
# fall through.
nop
nop
nop
nop
# case FFI_SYSV_TYPE_SMALL_STRUCT + 7. Seven byte struct.
.Lret_type21:
# fall through.
nop
nop
nop
nop
# case FFI_SYSV_TYPE_SMALL_STRUCT + 8. Eight byte struct.
.Lret_type22:
# this one handles the above unhandled structs.
lwz %r3,0(%r6)
lwz %r4,4(%r6)
bl __lshrdi3 # libgcc function to shift r3/r4, shift value in r5.
b .Lfinish
# case done
.Lfinish:
lwz %r0,148(%r1)
mtlr %r0
addi %r1,%r1,144
blr
nop
# case FFI_TYPE_INT
lwz %r3,112+0(%r1)
mtlr %r0
.Lfinish:
addi %r1,%r1,144
blr
# case FFI_TYPE_FLOAT
lfs %f1,112+0(%r1)
mtlr %r0
addi %r1,%r1,144
blr
# case FFI_TYPE_DOUBLE
lfd %f1,112+0(%r1)
mtlr %r0
addi %r1,%r1,144
blr
# case FFI_TYPE_LONGDOUBLE
lfd %f1,112+0(%r1)
lfd %f2,112+8(%r1)
mtlr %r0
b .Lfinish
# case FFI_TYPE_UINT8
lbz %r3,112+3(%r1)
mtlr %r0
addi %r1,%r1,144
blr
# case FFI_TYPE_SINT8
lbz %r3,112+3(%r1)
extsb %r3,%r3
mtlr %r0
b .Lfinish
# case FFI_TYPE_UINT16
lhz %r3,112+2(%r1)
mtlr %r0
addi %r1,%r1,144
blr
# case FFI_TYPE_SINT16
lha %r3,112+2(%r1)
mtlr %r0
addi %r1,%r1,144
blr
# case FFI_TYPE_UINT32
lwz %r3,112+0(%r1)
mtlr %r0
addi %r1,%r1,144
blr
# case FFI_TYPE_SINT32
lwz %r3,112+0(%r1)
mtlr %r0
addi %r1,%r1,144
blr
# case FFI_TYPE_UINT64
lwz %r3,112+0(%r1)
lwz %r4,112+4(%r1)
mtlr %r0
b .Lfinish
# case FFI_TYPE_SINT64
lwz %r3,112+0(%r1)
lwz %r4,112+4(%r1)
mtlr %r0
b .Lfinish
# case FFI_TYPE_STRUCT
mtlr %r0
addi %r1,%r1,144
blr
nop
# case FFI_TYPE_POINTER
lwz %r3,112+0(%r1)
mtlr %r0
addi %r1,%r1,144
blr
# case FFI_TYPE_UINT128
lwz %r3,112+0(%r1)
lwz %r4,112+4(%r1)
lwz %r5,112+8(%r1)
bl .Luint128
# The return types below are only used when the ABI type is FFI_SYSV.
# case FFI_SYSV_TYPE_SMALL_STRUCT + 1. One byte struct.
lbz %r3,112+0(%r1)
mtlr %r0
addi %r1,%r1,144
blr
# case FFI_SYSV_TYPE_SMALL_STRUCT + 2. Two byte struct.
lhz %r3,112+0(%r1)
mtlr %r0
addi %r1,%r1,144
blr
# case FFI_SYSV_TYPE_SMALL_STRUCT + 3. Three byte struct.
lwz %r3,112+0(%r1)
srwi %r3,%r3,8
mtlr %r0
b .Lfinish
# case FFI_SYSV_TYPE_SMALL_STRUCT + 4. Four byte struct.
lwz %r3,112+0(%r1)
mtlr %r0
addi %r1,%r1,144
blr
# case FFI_SYSV_TYPE_SMALL_STRUCT + 5. Five byte struct.
lwz %r3,112+0(%r1)
lwz %r4,112+4(%r1)
li %r5,24
b .Lstruct567
# case FFI_SYSV_TYPE_SMALL_STRUCT + 6. Six byte struct.
lwz %r3,112+0(%r1)
lwz %r4,112+4(%r1)
li %r5,16
b .Lstruct567
# case FFI_SYSV_TYPE_SMALL_STRUCT + 7. Seven byte struct.
lwz %r3,112+0(%r1)
lwz %r4,112+4(%r1)
li %r5,8
b .Lstruct567
# case FFI_SYSV_TYPE_SMALL_STRUCT + 8. Eight byte struct.
lwz %r3,112+0(%r1)
lwz %r4,112+4(%r1)
mtlr %r0
b .Lfinish
.Lstruct567:
subfic %r6,%r5,32
srw %r4,%r4,%r5
slw %r6,%r3,%r6
srw %r3,%r3,%r5
or %r4,%r6,%r4
mtlr %r0
addi %r1,%r1,144
blr
.Luint128:
lwz %r6,112+12(%r1)
mtlr %r0
addi %r1,%r1,144
blr
END(ffi_closure_SYSV)
.section ".eh_frame",EH_FRAME_FLAGS,@progbits

View File

@@ -1,5 +1,6 @@
/* -----------------------------------------------------------------------
sysv.h - Copyright (c) 1998 Geoffrey Keating
sysv.S - Copyright (c) 1998 Geoffrey Keating
Copyright (C) 2007 Free Software Foundation, Inc
PowerPC Assembly glue.
@@ -98,13 +99,17 @@ ENTRY(ffi_call_SYSV)
bctrl
/* Now, deal with the return value. */
mtcrf 0x01,%r31
mtcrf 0x01,%r31 /* cr7 */
bt- 31,L(small_struct_return_value)
bt- 30,L(done_return_value)
bt- 29,L(fp_return_value)
stw %r3,0(%r30)
bf+ 28,L(done_return_value)
stw %r4,4(%r30)
mtcrf 0x02,%r31 /* cr6 */
bf 27,L(done_return_value)
stw %r5,8(%r30)
stw %r6,12(%r30)
/* Fall through... */
L(done_return_value):
@@ -121,6 +126,9 @@ L(done_return_value):
L(fp_return_value):
bf 28,L(float_return_value)
stfd %f1,0(%r30)
mtcrf 0x02,%r31 /* cr6 */
bf 27,L(done_return_value)
stfd %f2,8(%r30)
b L(done_return_value)
L(float_return_value):
stfs %f1,0(%r30)
@@ -140,8 +148,14 @@ L(smst_one_register):
b L(done_return_value)
L(smst_two_register):
rlwinm %r5,%r31,5+23,32-5,31 /* Extract the value to shift. */
bl __ashldi3 /* libgcc function to shift r3/r4,
shift value in r5. */
cmpwi %r5,0
subfic %r9,%r5,32
slw %r29,%r3,%r5
srw %r9,%r4,%r9
beq- L(smst_8byte)
or %r3,%r9,%r29
slw %r4,%r4,%r5
L(smst_8byte):
stw %r3,0(%r30)
stw %r4,4(%r30)
b L(done_return_value)