* 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
+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.
2005-07-19 Andreas Tobler <a.tobler@schweiz.ch>
* Makefile.am (nodist_libffi_la_SOURCES): Add POWERPC_FREEBSD.
/* -----------------------------------------------------------------------
/* -----------------------------------------------------------------------
- ffi.c - Copyright (c) 2002, 2003, 2004 Kaz Kojima
+ ffi.c - Copyright (c) 2002, 2003, 2004, 2005 Kaz Kojima
SuperH Foreign Function Interface
SuperH Foreign Function Interface
/*@dependent@*/ void **avalue)
{
extended_cif ecif;
/*@dependent@*/ void **avalue)
{
extended_cif ecif;
ecif.cif = cif;
ecif.avalue = avalue;
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 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@*/
(cif->rtype->type == FFI_TYPE_STRUCT))
{
/*@-sysunrecog@*/
}
else
ecif.rvalue = rvalue;
}
else
ecif.rvalue = rvalue;
+
+ 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);
}
extern void ffi_closure_SYSV (void);
/* -----------------------------------------------------------------------
/* -----------------------------------------------------------------------
- ffi.c - Copyright (c) 2003 Kaz Kojima
+ ffi.c - Copyright (c) 2003, 2004 Kaz Kojima
SuperH SHmedia Foreign Function Interface
SuperH SHmedia Foreign Function Interface
#define NGREGARG 8
#define NFREGARG 12
#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)
{
static int
return_type (ffi_type *arg)
{
if (arg->type != FFI_TYPE_STRUCT)
return arg->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. */
/* 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;
return FFI_TYPE_UINT64;
return FFI_TYPE_STRUCT;
for (i = 0, p_arg = ecif->cif->arg_types; i < avn; i++, p_arg++, p_argv++)
{
size_t z;
for (i = 0, p_arg = ecif->cif->arg_types; i < avn; i++, p_arg++, p_argv++)
{
size_t z;
+ align = (*p_arg)->alignment;
if (z < sizeof (UINT32))
{
switch ((*p_arg)->type)
if (z < sizeof (UINT32))
{
switch ((*p_arg)->type)
break;
case FFI_TYPE_STRUCT:
break;
case FFI_TYPE_STRUCT:
- *(UINT64 *) argp = (UINT64) *(UINT32 *)(*p_argv);
+ memcpy (argp, *p_argv, z);
}
argp += sizeof (UINT64);
}
}
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);
}
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);
{
*(UINT64 *) argp = *(UINT64 *) (*p_argv);
argp += sizeof (UINT64);
/*@dependent@*/ void **avalue)
{
extended_cif ecif;
/*@dependent@*/ void **avalue)
{
extended_cif ecif;
ecif.cif = cif;
ecif.avalue = avalue;
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 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@*/
(cif->rtype->type == FFI_TYPE_STRUCT))
{
/*@-sysunrecog@*/
+
+ 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);
}
extern void ffi_closure_SYSV (void);
/* Copy the caller's structure return value address so that the closure
returns the data directly to the caller. */
/* 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;
{
rvalue = *pgr;
greg = 1;
(closure->fun) (cif, rvalue, avalue, closure->user_data);
/* Tell ffi_closure_SYSV how to perform return type promotions. */
(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);
/* -----------------------------------------------------------------------
/* -----------------------------------------------------------------------
- sysv.S - Copyright (c) 2003 Kaz Kojima
+ sysv.S - Copyright (c) 2003, 2004 Kaz Kojima
SuperH SHmedia Foreign Function Interface
SuperH SHmedia Foreign Function Interface
st.q r15, 8, r28
st.l r15, 4, r18
st.l r15, 0, r14
st.q r15, 8, r28
st.l r15, 4, r18
st.l r15, 0, r14
+ add.l r15, r63, r14
+.LCFI2:
# add r4, r63, r28
add r5, r63, r29
add r6, r63, r30
# add r4, r63, r28
add r5, r63, r29
add r6, r63, r30
pt/l .L_epilogue, tr4
beqi/l r29, FFI_TYPE_INT, tr0
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
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
fst.s r31, OFS_FLT, fr0
blink tr4, r63
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
.L_ret_i:
st.l r31, 0, r2
# Fall
ENTRY(ffi_closure_SYSV)
.LFB2:
addi.l r15, -136, r15
ENTRY(ffi_closure_SYSV)
.LFB2:
addi.l r15, -136, r15
st.l r15, 12, r18
st.l r15, 8, r14
st.l r15, 4, r12
st.l r15, 12, r18
st.l r15, 8, r14
st.l r15, 4, r12
/* Stack layout:
...
64 bytes (register parameters)
/* Stack layout:
...
64 bytes (register parameters)
.LSCIE1:
.4byte 0x0 /* CIE Identifier Tag */
.byte 0x1 /* CIE Version */
.LSCIE1:
.4byte 0x0 /* CIE Identifier Tag */
.byte 0x1 /* CIE Version */
.ascii "zR\0" /* CIE Augmentation */
.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 */
.uleb128 0x1 /* CIE Code Alignment Factor */
.sleb128 -4 /* CIE Data Alignment Factor */
.byte 0x12 /* CIE RA Column */
.uleb128 0x1 /* Augmentation size */
.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
.byte 0xc /* DW_CFA_def_cfa */
.uleb128 0xf
.uleb128 0x0
.4byte datalabel .LEFDE1-datalabel .LASFDE1 /* FDE Length */
.LASFDE1:
.4byte datalabel .LASFDE1-datalabel __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 */
.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 */
.byte 0x4 /* DW_CFA_advance_loc4 */
.4byte datalabel .LCFI0-datalabel .LFB1
.byte 0xe /* DW_CFA_def_cfa_offset */
.uleb128 0x4
.byte 0xa0 /* DW_CFA_offset, column 0x20 */
.uleb128 0x2
.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
.byte 0xd /* DW_CFA_def_cfa_register */
.uleb128 0xe
.align 2
.4byte datalabel .LEFDE3-datalabel .LASFDE3 /* FDE Length */
.LASFDE3:
.4byte datalabel .LASFDE3-datalabel __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 */
.4byte datalabel .LFE2-datalabel .LFB2 /* FDE address range */
+#ifdef PIC
+ .uleb128 0x0 /* Augmentation size */
+#endif
.byte 0x4 /* DW_CFA_advance_loc4 */
.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 */
.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 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
.byte 0xd /* DW_CFA_def_cfa_register */
.uleb128 0xe
.align 2