ffi.c (ffi_call): Handle small structures correctly.
* src/sh/ffi.c (ffi_call): Handle small structures correctly. Remove empty line. * src/sh64/ffi.c (simple_type): Remove. (return_type): Handle small structures correctly. (ffi_prep_args): Likewise. (ffi_call): Likewise. (ffi_closure_helper_SYSV): Likewise. * src/sh64/sysv.S (ffi_call_SYSV): Handle 1, 2 and 4-byte return. Emit position independent code if PIC and remove wrong datalabel prefixes from EH data. From-SVN: r102210
This commit is contained in:
parent
3a664c1c00
commit
5d0317fccc
4 changed files with 119 additions and 54 deletions
|
@ -1,3 +1,16 @@
|
|||
2005-07-20 Kaz Kojima <kkojima@gcc.gnu.org>
|
||||
|
||||
* src/sh/ffi.c (ffi_call): Handle small structures correctly.
|
||||
Remove empty line.
|
||||
* src/sh64/ffi.c (simple_type): Remove.
|
||||
(return_type): Handle small structures correctly.
|
||||
(ffi_prep_args): Likewise.
|
||||
(ffi_call): Likewise.
|
||||
(ffi_closure_helper_SYSV): Likewise.
|
||||
* src/sh64/sysv.S (ffi_call_SYSV): Handle 1, 2 and 4-byte return.
|
||||
Emit position independent code if PIC and remove wrong datalabel
|
||||
prefixes from EH data.
|
||||
|
||||
2005-07-19 Andreas Tobler <a.tobler@schweiz.ch>
|
||||
|
||||
* Makefile.am (nodist_libffi_la_SOURCES): Add POWERPC_FREEBSD.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -----------------------------------------------------------------------
|
||||
ffi.c - Copyright (c) 2002, 2003, 2004 Kaz Kojima
|
||||
ffi.c - Copyright (c) 2002, 2003, 2004, 2005 Kaz Kojima
|
||||
|
||||
SuperH Foreign Function Interface
|
||||
|
||||
|
@ -427,6 +427,7 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif,
|
|||
/*@dependent@*/ void **avalue)
|
||||
{
|
||||
extended_cif ecif;
|
||||
UINT64 trvalue;
|
||||
|
||||
ecif.cif = cif;
|
||||
ecif.avalue = avalue;
|
||||
|
@ -434,7 +435,10 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif,
|
|||
/* 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 (cif->rtype->type == FFI_TYPE_STRUCT
|
||||
&& return_type (cif->rtype) != FFI_TYPE_STRUCT)
|
||||
ecif.rvalue = &trvalue;
|
||||
else if ((rvalue == NULL) &&
|
||||
(cif->rtype->type == FFI_TYPE_STRUCT))
|
||||
{
|
||||
/*@-sysunrecog@*/
|
||||
|
@ -443,7 +447,6 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif,
|
|||
}
|
||||
else
|
||||
ecif.rvalue = rvalue;
|
||||
|
||||
|
||||
switch (cif->abi)
|
||||
{
|
||||
|
@ -457,6 +460,11 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif,
|
|||
FFI_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
if (rvalue
|
||||
&& cif->rtype->type == FFI_TYPE_STRUCT
|
||||
&& return_type (cif->rtype) != FFI_TYPE_STRUCT)
|
||||
memcpy (rvalue, &trvalue, cif->rtype->size);
|
||||
}
|
||||
|
||||
extern void ffi_closure_SYSV (void);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -----------------------------------------------------------------------
|
||||
ffi.c - Copyright (c) 2003 Kaz Kojima
|
||||
ffi.c - Copyright (c) 2003, 2004 Kaz Kojima
|
||||
|
||||
SuperH SHmedia Foreign Function Interface
|
||||
|
||||
|
@ -31,48 +31,21 @@
|
|||
#define NGREGARG 8
|
||||
#define NFREGARG 12
|
||||
|
||||
/* If the structure has essentialy an unique element, return its type. */
|
||||
static int
|
||||
simple_type (ffi_type *arg)
|
||||
{
|
||||
if (arg->type != FFI_TYPE_STRUCT)
|
||||
return arg->type;
|
||||
else if (arg->elements[1])
|
||||
return FFI_TYPE_STRUCT;
|
||||
|
||||
return simple_type (arg->elements[0]);
|
||||
}
|
||||
|
||||
static int
|
||||
return_type (ffi_type *arg)
|
||||
{
|
||||
unsigned short type;
|
||||
|
||||
if (arg->type != FFI_TYPE_STRUCT)
|
||||
return arg->type;
|
||||
|
||||
type = simple_type (arg->elements[0]);
|
||||
if (! arg->elements[1])
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case FFI_TYPE_SINT8:
|
||||
case FFI_TYPE_UINT8:
|
||||
case FFI_TYPE_SINT16:
|
||||
case FFI_TYPE_UINT16:
|
||||
case FFI_TYPE_SINT32:
|
||||
case FFI_TYPE_UINT32:
|
||||
case FFI_TYPE_SINT64:
|
||||
case FFI_TYPE_UINT64:
|
||||
return FFI_TYPE_UINT64;
|
||||
|
||||
default:
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
/* gcc uses r2 if the result can be packed in on register. */
|
||||
if (arg->size <= sizeof (UINT64))
|
||||
if (arg->size <= sizeof (UINT8))
|
||||
return FFI_TYPE_UINT8;
|
||||
else if (arg->size <= sizeof (UINT16))
|
||||
return FFI_TYPE_UINT16;
|
||||
else if (arg->size <= sizeof (UINT32))
|
||||
return FFI_TYPE_UINT32;
|
||||
else if (arg->size <= sizeof (UINT64))
|
||||
return FFI_TYPE_UINT64;
|
||||
|
||||
return FFI_TYPE_STRUCT;
|
||||
|
@ -105,8 +78,10 @@ void ffi_prep_args(char *stack, extended_cif *ecif)
|
|||
for (i = 0, p_arg = ecif->cif->arg_types; i < avn; i++, p_arg++, p_argv++)
|
||||
{
|
||||
size_t z;
|
||||
int align;
|
||||
|
||||
z = (*p_arg)->size;
|
||||
align = (*p_arg)->alignment;
|
||||
if (z < sizeof (UINT32))
|
||||
{
|
||||
switch ((*p_arg)->type)
|
||||
|
@ -128,7 +103,7 @@ void ffi_prep_args(char *stack, extended_cif *ecif)
|
|||
break;
|
||||
|
||||
case FFI_TYPE_STRUCT:
|
||||
*(UINT64 *) argp = (UINT64) *(UINT32 *)(*p_argv);
|
||||
memcpy (argp, *p_argv, z);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -136,12 +111,31 @@ void ffi_prep_args(char *stack, extended_cif *ecif)
|
|||
}
|
||||
argp += sizeof (UINT64);
|
||||
}
|
||||
else if (z == sizeof (UINT32))
|
||||
else if (z == sizeof (UINT32) && align == sizeof (UINT32))
|
||||
{
|
||||
*(UINT64 *) argp = (UINT64) *(UINT32 *) (*p_argv);
|
||||
switch ((*p_arg)->type)
|
||||
{
|
||||
case FFI_TYPE_INT:
|
||||
case FFI_TYPE_SINT32:
|
||||
*(SINT64 *) argp = (SINT64) *(SINT32 *) (*p_argv);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_FLOAT:
|
||||
case FFI_TYPE_POINTER:
|
||||
case FFI_TYPE_UINT32:
|
||||
case FFI_TYPE_STRUCT:
|
||||
*(UINT64 *) argp = (UINT64) *(UINT32 *) (*p_argv);
|
||||
break;
|
||||
|
||||
default:
|
||||
FFI_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
argp += sizeof (UINT64);
|
||||
}
|
||||
else if (z == sizeof (UINT64))
|
||||
else if (z == sizeof (UINT64)
|
||||
&& align == sizeof (UINT64)
|
||||
&& ((int) *p_argv & (sizeof (UINT64) - 1)) == 0)
|
||||
{
|
||||
*(UINT64 *) argp = *(UINT64 *) (*p_argv);
|
||||
argp += sizeof (UINT64);
|
||||
|
@ -254,6 +248,7 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif,
|
|||
/*@dependent@*/ void **avalue)
|
||||
{
|
||||
extended_cif ecif;
|
||||
UINT64 trvalue;
|
||||
|
||||
ecif.cif = cif;
|
||||
ecif.avalue = avalue;
|
||||
|
@ -261,7 +256,10 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif,
|
|||
/* 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 (cif->rtype->type == FFI_TYPE_STRUCT
|
||||
&& return_type (cif->rtype) != FFI_TYPE_STRUCT)
|
||||
ecif.rvalue = &trvalue;
|
||||
else if ((rvalue == NULL) &&
|
||||
(cif->rtype->type == FFI_TYPE_STRUCT))
|
||||
{
|
||||
/*@-sysunrecog@*/
|
||||
|
@ -283,6 +281,11 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif,
|
|||
FFI_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
if (rvalue
|
||||
&& cif->rtype->type == FFI_TYPE_STRUCT
|
||||
&& return_type (cif->rtype) != FFI_TYPE_STRUCT)
|
||||
memcpy (rvalue, &trvalue, cif->rtype->size);
|
||||
}
|
||||
|
||||
extern void ffi_closure_SYSV (void);
|
||||
|
@ -353,7 +356,7 @@ ffi_closure_helper_SYSV (ffi_closure *closure, UINT64 *rvalue,
|
|||
|
||||
/* Copy the caller's structure return value address so that the closure
|
||||
returns the data directly to the caller. */
|
||||
if (cif->rtype->type == FFI_TYPE_STRUCT)
|
||||
if (return_type (cif->rtype) == FFI_TYPE_STRUCT)
|
||||
{
|
||||
rvalue = *pgr;
|
||||
greg = 1;
|
||||
|
@ -443,6 +446,6 @@ ffi_closure_helper_SYSV (ffi_closure *closure, UINT64 *rvalue,
|
|||
(closure->fun) (cif, rvalue, avalue, closure->user_data);
|
||||
|
||||
/* Tell ffi_closure_SYSV how to perform return type promotions. */
|
||||
return cif->rtype->type;
|
||||
return return_type (cif->rtype);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -----------------------------------------------------------------------
|
||||
sysv.S - Copyright (c) 2003 Kaz Kojima
|
||||
sysv.S - Copyright (c) 2003, 2004 Kaz Kojima
|
||||
|
||||
SuperH SHmedia Foreign Function Interface
|
||||
|
||||
|
@ -64,8 +64,9 @@ ENTRY(ffi_call_SYSV)
|
|||
st.q r15, 8, r28
|
||||
st.l r15, 4, r18
|
||||
st.l r15, 0, r14
|
||||
add.l r15, r63, r14
|
||||
.LCFI1:
|
||||
add.l r15, r63, r14
|
||||
.LCFI2:
|
||||
# add r4, r63, r28
|
||||
add r5, r63, r29
|
||||
add r6, r63, r30
|
||||
|
@ -252,10 +253,17 @@ ENTRY(ffi_call_SYSV)
|
|||
pt/l .L_epilogue, tr4
|
||||
|
||||
beqi/l r29, FFI_TYPE_INT, tr0
|
||||
beqi/l r29, FFI_TYPE_UINT32, tr0
|
||||
beqi/l r29, FFI_TYPE_SINT64, tr1
|
||||
beqi/l r29, FFI_TYPE_UINT64, tr1
|
||||
beqi/l r29, FFI_TYPE_DOUBLE, tr2
|
||||
beqi/l r29, FFI_TYPE_FLOAT, tr3
|
||||
|
||||
pt/l .L_ret_q, tr0
|
||||
pt/l .L_ret_h, tr1
|
||||
|
||||
beqi/l r29, FFI_TYPE_UINT8, tr0
|
||||
beqi/l r29, FFI_TYPE_UINT16, tr1
|
||||
blink tr4, r63
|
||||
|
||||
.L_ret_d:
|
||||
|
@ -270,6 +278,14 @@ ENTRY(ffi_call_SYSV)
|
|||
fst.s r31, OFS_FLT, fr0
|
||||
blink tr4, r63
|
||||
|
||||
.L_ret_q:
|
||||
st.b r31, 0, r2
|
||||
blink tr4, r63
|
||||
|
||||
.L_ret_h:
|
||||
st.w r31, 0, r2
|
||||
blink tr4, r63
|
||||
|
||||
.L_ret_i:
|
||||
st.l r31, 0, r2
|
||||
# Fall
|
||||
|
@ -297,12 +313,13 @@ ENTRY(ffi_call_SYSV)
|
|||
ENTRY(ffi_closure_SYSV)
|
||||
.LFB2:
|
||||
addi.l r15, -136, r15
|
||||
.LCFI2:
|
||||
.LCFI3:
|
||||
st.l r15, 12, r18
|
||||
st.l r15, 8, r14
|
||||
st.l r15, 4, r12
|
||||
.LCFI4:
|
||||
add r15, r63, r14
|
||||
.LCFI3:
|
||||
.LCFI5:
|
||||
/* Stack layout:
|
||||
...
|
||||
64 bytes (register parameters)
|
||||
|
@ -418,12 +435,18 @@ __FRAME_BEGIN__:
|
|||
.LSCIE1:
|
||||
.4byte 0x0 /* CIE Identifier Tag */
|
||||
.byte 0x1 /* CIE Version */
|
||||
#ifdef PIC
|
||||
.ascii "zR\0" /* CIE Augmentation */
|
||||
#else
|
||||
.byte 0x0 /* CIE Augmentation */
|
||||
#endif
|
||||
.uleb128 0x1 /* CIE Code Alignment Factor */
|
||||
.sleb128 -4 /* CIE Data Alignment Factor */
|
||||
.byte 0x12 /* CIE RA Column */
|
||||
#ifdef PIC
|
||||
.uleb128 0x1 /* Augmentation size */
|
||||
.byte 0x1b /* FDE Encoding (pcrel sdata4) */
|
||||
.byte 0x10 /* FDE Encoding (pcrel) */
|
||||
#endif
|
||||
.byte 0xc /* DW_CFA_def_cfa */
|
||||
.uleb128 0xf
|
||||
.uleb128 0x0
|
||||
|
@ -433,8 +456,15 @@ __FRAME_BEGIN__:
|
|||
.4byte datalabel .LEFDE1-datalabel .LASFDE1 /* FDE Length */
|
||||
.LASFDE1:
|
||||
.4byte datalabel .LASFDE1-datalabel __FRAME_BEGIN__
|
||||
.4byte datalabel .LFB1-. /* FDE initial location */
|
||||
#ifdef PIC
|
||||
.4byte .LFB1-. /* FDE initial location */
|
||||
#else
|
||||
.4byte .LFB1 /* FDE initial location */
|
||||
#endif
|
||||
.4byte datalabel .LFE1-datalabel .LFB1 /* FDE address range */
|
||||
#ifdef PIC
|
||||
.uleb128 0x0 /* Augmentation size */
|
||||
#endif
|
||||
.byte 0x4 /* DW_CFA_advance_loc4 */
|
||||
.4byte datalabel .LCFI0-datalabel .LFB1
|
||||
.byte 0xe /* DW_CFA_def_cfa_offset */
|
||||
|
@ -455,6 +485,8 @@ __FRAME_BEGIN__:
|
|||
.uleb128 0x4
|
||||
.byte 0xa0 /* DW_CFA_offset, column 0x20 */
|
||||
.uleb128 0x2
|
||||
.byte 0x4 /* DW_CFA_advance_loc4 */
|
||||
.4byte datalabel .LCFI2-datalabel .LCFI1
|
||||
.byte 0xd /* DW_CFA_def_cfa_register */
|
||||
.uleb128 0xe
|
||||
.align 2
|
||||
|
@ -464,20 +496,29 @@ __FRAME_BEGIN__:
|
|||
.4byte datalabel .LEFDE3-datalabel .LASFDE3 /* FDE Length */
|
||||
.LASFDE3:
|
||||
.4byte datalabel .LASFDE3-datalabel __FRAME_BEGIN__
|
||||
.4byte datalabel .LFB2-. /* FDE initial location */
|
||||
#ifdef PIC
|
||||
.4byte .LFB2-. /* FDE initial location */
|
||||
#else
|
||||
.4byte .LFB2 /* FDE initial location */
|
||||
#endif
|
||||
.4byte datalabel .LFE2-datalabel .LFB2 /* FDE address range */
|
||||
#ifdef PIC
|
||||
.uleb128 0x0 /* Augmentation size */
|
||||
#endif
|
||||
.byte 0x4 /* DW_CFA_advance_loc4 */
|
||||
.4byte datalabel .LCFI2-datalabel .LFB2
|
||||
.4byte datalabel .LCFI3-datalabel .LFB2
|
||||
.byte 0xe /* DW_CFA_def_cfa_offset */
|
||||
.uleb128 0x88
|
||||
.byte 0x4 /* DW_CFA_advance_loc4 */
|
||||
.4byte datalabel .LCFI3-datalabel .LCFI2
|
||||
.4byte datalabel .LCFI4-datalabel .LCFI3
|
||||
.byte 0x8c /* DW_CFA_offset, column 0xc */
|
||||
.uleb128 0x21
|
||||
.byte 0x8e /* DW_CFA_offset, column 0xe */
|
||||
.uleb128 0x20
|
||||
.byte 0x92 /* DW_CFA_offset, column 0x12 */
|
||||
.uleb128 0x1f
|
||||
.byte 0x4 /* DW_CFA_advance_loc4 */
|
||||
.4byte datalabel .LCFI5-datalabel .LCFI4
|
||||
.byte 0xd /* DW_CFA_def_cfa_register */
|
||||
.uleb128 0xe
|
||||
.align 2
|
||||
|
|
Loading…
Add table
Reference in a new issue