Commit 5d0317fc by Kaz Kojima

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
parent 3a664c1c
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> 2005-07-19 Andreas Tobler <a.tobler@schweiz.ch>
* Makefile.am (nodist_libffi_la_SOURCES): Add POWERPC_FREEBSD. * 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
...@@ -427,6 +427,7 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif, ...@@ -427,6 +427,7 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif,
/*@dependent@*/ void **avalue) /*@dependent@*/ void **avalue)
{ {
extended_cif ecif; extended_cif ecif;
UINT64 trvalue;
ecif.cif = cif; ecif.cif = cif;
ecif.avalue = avalue; ecif.avalue = avalue;
...@@ -434,7 +435,10 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif, ...@@ -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 */ /* If the return value is a struct and we don't have a return */
/* value address then we need to make one */ /* 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)) (cif->rtype->type == FFI_TYPE_STRUCT))
{ {
/*@-sysunrecog@*/ /*@-sysunrecog@*/
...@@ -443,7 +447,6 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif, ...@@ -443,7 +447,6 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif,
} }
else else
ecif.rvalue = rvalue; ecif.rvalue = rvalue;
switch (cif->abi) switch (cif->abi)
{ {
...@@ -457,6 +460,11 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif, ...@@ -457,6 +460,11 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif,
FFI_ASSERT(0); FFI_ASSERT(0);
break; 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); 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
...@@ -31,48 +31,21 @@ ...@@ -31,48 +31,21 @@
#define NGREGARG 8 #define NGREGARG 8
#define NFREGARG 12 #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 static int
return_type (ffi_type *arg) return_type (ffi_type *arg)
{ {
unsigned short type;
if (arg->type != FFI_TYPE_STRUCT) if (arg->type != FFI_TYPE_STRUCT)
return arg->type; 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_UINT64;
return FFI_TYPE_STRUCT; return FFI_TYPE_STRUCT;
...@@ -105,8 +78,10 @@ void ffi_prep_args(char *stack, extended_cif *ecif) ...@@ -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++) for (i = 0, p_arg = ecif->cif->arg_types; i < avn; i++, p_arg++, p_argv++)
{ {
size_t z; size_t z;
int align;
z = (*p_arg)->size; z = (*p_arg)->size;
align = (*p_arg)->alignment;
if (z < sizeof (UINT32)) if (z < sizeof (UINT32))
{ {
switch ((*p_arg)->type) switch ((*p_arg)->type)
...@@ -128,7 +103,7 @@ void ffi_prep_args(char *stack, extended_cif *ecif) ...@@ -128,7 +103,7 @@ void ffi_prep_args(char *stack, extended_cif *ecif)
break; break;
case FFI_TYPE_STRUCT: case FFI_TYPE_STRUCT:
*(UINT64 *) argp = (UINT64) *(UINT32 *)(*p_argv); memcpy (argp, *p_argv, z);
break; break;
default: default:
...@@ -136,12 +111,31 @@ void ffi_prep_args(char *stack, extended_cif *ecif) ...@@ -136,12 +111,31 @@ void ffi_prep_args(char *stack, extended_cif *ecif)
} }
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); *(UINT64 *) argp = *(UINT64 *) (*p_argv);
argp += sizeof (UINT64); argp += sizeof (UINT64);
...@@ -254,6 +248,7 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif, ...@@ -254,6 +248,7 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif,
/*@dependent@*/ void **avalue) /*@dependent@*/ void **avalue)
{ {
extended_cif ecif; extended_cif ecif;
UINT64 trvalue;
ecif.cif = cif; ecif.cif = cif;
ecif.avalue = avalue; ecif.avalue = avalue;
...@@ -261,7 +256,10 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif, ...@@ -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 */ /* If the return value is a struct and we don't have a return */
/* value address then we need to make one */ /* 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)) (cif->rtype->type == FFI_TYPE_STRUCT))
{ {
/*@-sysunrecog@*/ /*@-sysunrecog@*/
...@@ -283,6 +281,11 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif, ...@@ -283,6 +281,11 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif,
FFI_ASSERT(0); FFI_ASSERT(0);
break; 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); extern void ffi_closure_SYSV (void);
...@@ -353,7 +356,7 @@ ffi_closure_helper_SYSV (ffi_closure *closure, UINT64 *rvalue, ...@@ -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 /* Copy the caller's structure return value address so that the closure
returns the data directly to the caller. */ returns the data directly to the caller. */
if (cif->rtype->type == FFI_TYPE_STRUCT) if (return_type (cif->rtype) == FFI_TYPE_STRUCT)
{ {
rvalue = *pgr; rvalue = *pgr;
greg = 1; greg = 1;
...@@ -443,6 +446,6 @@ ffi_closure_helper_SYSV (ffi_closure *closure, UINT64 *rvalue, ...@@ -443,6 +446,6 @@ ffi_closure_helper_SYSV (ffi_closure *closure, UINT64 *rvalue,
(closure->fun) (cif, rvalue, avalue, closure->user_data); (closure->fun) (cif, rvalue, avalue, closure->user_data);
/* Tell ffi_closure_SYSV how to perform return type promotions. */ /* 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
...@@ -64,8 +64,9 @@ ENTRY(ffi_call_SYSV) ...@@ -64,8 +64,9 @@ ENTRY(ffi_call_SYSV)
st.q r15, 8, r28 st.q r15, 8, r28
st.l r15, 4, r18 st.l r15, 4, r18
st.l r15, 0, r14 st.l r15, 0, r14
add.l r15, r63, r14
.LCFI1: .LCFI1:
add.l r15, r63, r14
.LCFI2:
# add r4, r63, r28 # add r4, r63, r28
add r5, r63, r29 add r5, r63, r29
add r6, r63, r30 add r6, r63, r30
...@@ -252,10 +253,17 @@ ENTRY(ffi_call_SYSV) ...@@ -252,10 +253,17 @@ ENTRY(ffi_call_SYSV)
pt/l .L_epilogue, tr4 pt/l .L_epilogue, tr4
beqi/l r29, FFI_TYPE_INT, tr0 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_SINT64, tr1
beqi/l r29, FFI_TYPE_UINT64, tr1 beqi/l r29, FFI_TYPE_UINT64, tr1
beqi/l r29, FFI_TYPE_DOUBLE, tr2 beqi/l r29, FFI_TYPE_DOUBLE, tr2
beqi/l r29, FFI_TYPE_FLOAT, tr3 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 blink tr4, r63
.L_ret_d: .L_ret_d:
...@@ -270,6 +278,14 @@ ENTRY(ffi_call_SYSV) ...@@ -270,6 +278,14 @@ ENTRY(ffi_call_SYSV)
fst.s r31, OFS_FLT, fr0 fst.s r31, OFS_FLT, fr0
blink tr4, r63 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: .L_ret_i:
st.l r31, 0, r2 st.l r31, 0, r2
# Fall # Fall
...@@ -297,12 +313,13 @@ ENTRY(ffi_call_SYSV) ...@@ -297,12 +313,13 @@ ENTRY(ffi_call_SYSV)
ENTRY(ffi_closure_SYSV) ENTRY(ffi_closure_SYSV)
.LFB2: .LFB2:
addi.l r15, -136, r15 addi.l r15, -136, r15
.LCFI2: .LCFI3:
st.l r15, 12, r18 st.l r15, 12, r18
st.l r15, 8, r14 st.l r15, 8, r14
st.l r15, 4, r12 st.l r15, 4, r12
.LCFI4:
add r15, r63, r14 add r15, r63, r14
.LCFI3: .LCFI5:
/* Stack layout: /* Stack layout:
... ...
64 bytes (register parameters) 64 bytes (register parameters)
...@@ -418,12 +435,18 @@ __FRAME_BEGIN__: ...@@ -418,12 +435,18 @@ __FRAME_BEGIN__:
.LSCIE1: .LSCIE1:
.4byte 0x0 /* CIE Identifier Tag */ .4byte 0x0 /* CIE Identifier Tag */
.byte 0x1 /* CIE Version */ .byte 0x1 /* CIE Version */
#ifdef PIC
.ascii "zR\0" /* CIE Augmentation */ .ascii "zR\0" /* CIE Augmentation */
#else
.byte 0x0 /* CIE Augmentation */
#endif
.uleb128 0x1 /* CIE Code Alignment Factor */ .uleb128 0x1 /* CIE Code Alignment Factor */
.sleb128 -4 /* CIE Data Alignment Factor */ .sleb128 -4 /* CIE Data Alignment Factor */
.byte 0x12 /* CIE RA Column */ .byte 0x12 /* CIE RA Column */
#ifdef PIC
.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 */ .byte 0xc /* DW_CFA_def_cfa */
.uleb128 0xf .uleb128 0xf
.uleb128 0x0 .uleb128 0x0
...@@ -433,8 +456,15 @@ __FRAME_BEGIN__: ...@@ -433,8 +456,15 @@ __FRAME_BEGIN__:
.4byte datalabel .LEFDE1-datalabel .LASFDE1 /* FDE Length */ .4byte datalabel .LEFDE1-datalabel .LASFDE1 /* FDE Length */
.LASFDE1: .LASFDE1:
.4byte datalabel .LASFDE1-datalabel __FRAME_BEGIN__ .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 */ .byte 0x4 /* DW_CFA_advance_loc4 */
.4byte datalabel .LCFI0-datalabel .LFB1 .4byte datalabel .LCFI0-datalabel .LFB1
.byte 0xe /* DW_CFA_def_cfa_offset */ .byte 0xe /* DW_CFA_def_cfa_offset */
...@@ -455,6 +485,8 @@ __FRAME_BEGIN__: ...@@ -455,6 +485,8 @@ __FRAME_BEGIN__:
.uleb128 0x4 .uleb128 0x4
.byte 0xa0 /* DW_CFA_offset, column 0x20 */ .byte 0xa0 /* DW_CFA_offset, column 0x20 */
.uleb128 0x2 .uleb128 0x2
.byte 0x4 /* DW_CFA_advance_loc4 */
.4byte datalabel .LCFI2-datalabel .LCFI1
.byte 0xd /* DW_CFA_def_cfa_register */ .byte 0xd /* DW_CFA_def_cfa_register */
.uleb128 0xe .uleb128 0xe
.align 2 .align 2
...@@ -464,20 +496,29 @@ __FRAME_BEGIN__: ...@@ -464,20 +496,29 @@ __FRAME_BEGIN__:
.4byte datalabel .LEFDE3-datalabel .LASFDE3 /* FDE Length */ .4byte datalabel .LEFDE3-datalabel .LASFDE3 /* FDE Length */
.LASFDE3: .LASFDE3:
.4byte datalabel .LASFDE3-datalabel __FRAME_BEGIN__ .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 */ .byte 0xe /* DW_CFA_def_cfa_offset */
.uleb128 0x88 .uleb128 0x88
.byte 0x4 /* DW_CFA_advance_loc4 */ .byte 0x4 /* DW_CFA_advance_loc4 */
.4byte datalabel .LCFI3-datalabel .LCFI2 .4byte datalabel .LCFI4-datalabel .LCFI3
.byte 0x8c /* DW_CFA_offset, column 0xc */ .byte 0x8c /* DW_CFA_offset, column 0xc */
.uleb128 0x21 .uleb128 0x21
.byte 0x8e /* DW_CFA_offset, column 0xe */ .byte 0x8e /* DW_CFA_offset, column 0xe */
.uleb128 0x20 .uleb128 0x20
.byte 0x92 /* DW_CFA_offset, column 0x12 */ .byte 0x92 /* DW_CFA_offset, column 0x12 */
.uleb128 0x1f .uleb128 0x1f
.byte 0x4 /* DW_CFA_advance_loc4 */
.4byte datalabel .LCFI5-datalabel .LCFI4
.byte 0xd /* DW_CFA_def_cfa_register */ .byte 0xd /* DW_CFA_def_cfa_register */
.uleb128 0xe .uleb128 0xe
.align 2 .align 2
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment