From: Kaz Kojima Date: Wed, 20 Jul 2005 23:32:01 +0000 (+0000) Subject: ffi.c (ffi_call): Handle small structures correctly. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=5d0317fccc05045d73439d30afb00cb710fa9a82;p=platform%2Fupstream%2Fgcc.git 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 --- diff --git a/libffi/ChangeLog b/libffi/ChangeLog index 00bd80c..bd6a638 100644 --- a/libffi/ChangeLog +++ b/libffi/ChangeLog @@ -1,3 +1,16 @@ +2005-07-20 Kaz Kojima + + * 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 * Makefile.am (nodist_libffi_la_SOURCES): Add POWERPC_FREEBSD. diff --git a/libffi/src/sh/ffi.c b/libffi/src/sh/ffi.c index 2045419..ddf562f 100644 --- a/libffi/src/sh/ffi.c +++ b/libffi/src/sh/ffi.c @@ -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); diff --git a/libffi/src/sh64/ffi.c b/libffi/src/sh64/ffi.c index 7709603..abf3f0d 100644 --- a/libffi/src/sh64/ffi.c +++ b/libffi/src/sh64/ffi.c @@ -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); } diff --git a/libffi/src/sh64/sysv.S b/libffi/src/sh64/sysv.S index 949f69f..19f1b51 100644 --- a/libffi/src/sh64/sysv.S +++ b/libffi/src/sh64/sysv.S @@ -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