From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 11636 invoked by alias); 30 Oct 2014 03:54:52 -0000 Mailing-List: contact libffi-discuss-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libffi-discuss-owner@sourceware.org Received: (qmail 11514 invoked by uid 89); 30 Oct 2014 03:54:51 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.3 required=5.0 tests=AWL,BAYES_00,FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-pd0-f178.google.com Received: from mail-pd0-f178.google.com (HELO mail-pd0-f178.google.com) (209.85.192.178) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Thu, 30 Oct 2014 03:54:48 +0000 Received: by mail-pd0-f178.google.com with SMTP id fp1so4287190pdb.37 for ; Wed, 29 Oct 2014 20:54:46 -0700 (PDT) X-Received: by 10.70.129.209 with SMTP id ny17mr599191pdb.163.1414641286715; Wed, 29 Oct 2014 20:54:46 -0700 (PDT) Received: from pike.twiddle.home (50-194-63-110-static.hfc.comcastbusiness.net. [50.194.63.110]) by mx.google.com with ESMTPSA id qh7sm5676184pab.48.2014.10.29.20.54.45 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 29 Oct 2014 20:54:45 -0700 (PDT) From: Richard Henderson To: libffi-discuss@sourceware.org Subject: [PATCH 1/4] alpha: Reorganize cif flags Date: Thu, 30 Oct 2014 03:54:00 -0000 Message-Id: <1414641281-15172-2-git-send-email-rth@twiddle.net> In-Reply-To: <1414641281-15172-1-git-send-email-rth@twiddle.net> References: <1414641281-15172-1-git-send-email-rth@twiddle.net> X-SW-Source: 2014/txt/msg00174.txt.bz2 Unties the backend from changes to FFI_TYPE_* constants, and allows compilation to succeed after the addition of FFI_TYPE_COMPLEX. Delete the hand-written unwind info. --- src/alpha/ffi.c | 63 +++++++--- src/alpha/internal.h | 19 +++ src/alpha/osf.S | 341 ++++++++++++++------------------------------------- 3 files changed, 160 insertions(+), 263 deletions(-) create mode 100644 src/alpha/internal.h diff --git a/src/alpha/ffi.c b/src/alpha/ffi.c index 192f691..519bd2c 100644 --- a/src/alpha/ffi.c +++ b/src/alpha/ffi.c @@ -28,6 +28,7 @@ #include #include #include +#include "internal.h" /* Force FFI_TYPE_LONGDOUBLE to be different than FFI_TYPE_DOUBLE; all further uses in this file will refer to the 128-bit type. */ @@ -48,6 +49,8 @@ extern void ffi_closure_osf(void) FFI_HIDDEN; ffi_status ffi_prep_cif_machdep(ffi_cif *cif) { + int flags; + /* Adjust cif->bytes to represent a minimum 6 words for the temporary register argument loading area. */ if (cif->bytes < 6*FFI_SIZEOF_ARG) @@ -56,21 +59,46 @@ ffi_prep_cif_machdep(ffi_cif *cif) /* Set the return type flag */ switch (cif->rtype->type) { - case FFI_TYPE_STRUCT: + case FFI_TYPE_VOID: + flags = ALPHA_FLAGS(ALPHA_ST_VOID, ALPHA_LD_VOID); + break; + case FFI_TYPE_INT: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: + flags = ALPHA_FLAGS(ALPHA_ST_INT, ALPHA_LD_INT32); + break; case FFI_TYPE_FLOAT: + flags = ALPHA_FLAGS(ALPHA_ST_FLOAT, ALPHA_LD_FLOAT); + break; case FFI_TYPE_DOUBLE: - cif->flags = cif->rtype->type; + flags = ALPHA_FLAGS(ALPHA_ST_DOUBLE, ALPHA_LD_DOUBLE); + break; + case FFI_TYPE_UINT8: + flags = ALPHA_FLAGS(ALPHA_ST_INT, ALPHA_LD_UINT8); + break; + case FFI_TYPE_SINT8: + flags = ALPHA_FLAGS(ALPHA_ST_INT, ALPHA_LD_SINT8); + break; + case FFI_TYPE_UINT16: + flags = ALPHA_FLAGS(ALPHA_ST_INT, ALPHA_LD_UINT16); + break; + case FFI_TYPE_SINT16: + flags = ALPHA_FLAGS(ALPHA_ST_INT, ALPHA_LD_SINT16); + break; + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + case FFI_TYPE_POINTER: + flags = ALPHA_FLAGS(ALPHA_ST_INT, ALPHA_LD_INT64); break; - case FFI_TYPE_LONGDOUBLE: - /* 128-bit long double is returned in memory, like a struct. */ - cif->flags = FFI_TYPE_STRUCT; + case FFI_TYPE_STRUCT: + /* Passed in memory, with a hidden pointer. */ + flags = ALPHA_RET_IN_MEM; break; - default: - cif->flags = FFI_TYPE_INT; - break; + abort(); } + cif->flags = flags; return FFI_OK; } @@ -80,20 +108,20 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) { unsigned long *stack, *argp; - long i, avn; + long i, avn, flags = cif->flags; ffi_type **arg_types; /* 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 && cif->flags == FFI_TYPE_STRUCT) + if (rvalue == NULL && flags == ALPHA_RET_IN_MEM) rvalue = alloca(cif->rtype->size); /* Allocate the space for the arguments, plus 4 words of temp space for ffi_call_osf. */ argp = stack = alloca(cif->bytes + 4*FFI_SIZEOF_ARG); - if (cif->flags == FFI_TYPE_STRUCT) - *(void **) argp++ = rvalue; + if (flags == ALPHA_RET_IN_MEM) + *argp++ = (unsigned long)rvalue; i = 0; avn = cif->nargs; @@ -166,7 +194,8 @@ ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) i++, arg_types++, avalue++; } - ffi_call_osf(stack, cif->bytes, cif->flags, rvalue, fn); + flags = (flags >> ALPHA_ST_SHIFT) & 0xff; + ffi_call_osf(stack, cif->bytes, flags, rvalue, fn); } @@ -211,16 +240,16 @@ ffi_closure_osf_inner(ffi_closure *closure, void *rvalue, unsigned long *argp) ffi_cif *cif; void **avalue; ffi_type **arg_types; - long i, avn, argn; + long i, avn, argn, flags; cif = closure->cif; avalue = alloca(cif->nargs * sizeof(void *)); - + flags = cif->flags; argn = 0; /* Copy the caller's structure return address to that the closure returns the data directly to the caller. */ - if (cif->flags == FFI_TYPE_STRUCT) + if (flags == ALPHA_RET_IN_MEM) { rvalue = (void *) argp[0]; argn = 1; @@ -284,5 +313,5 @@ ffi_closure_osf_inner(ffi_closure *closure, void *rvalue, unsigned long *argp) closure->fun (cif, rvalue, avalue, closure->user_data); /* Tell ffi_closure_osf how to perform return type promotions. */ - return cif->rtype->type; + return (flags >> ALPHA_LD_SHIFT) & 0xff; } diff --git a/src/alpha/internal.h b/src/alpha/internal.h new file mode 100644 index 0000000..664a2a6 --- /dev/null +++ b/src/alpha/internal.h @@ -0,0 +1,19 @@ +#define ALPHA_ST_VOID 0 +#define ALPHA_ST_INT 1 +#define ALPHA_ST_FLOAT 2 +#define ALPHA_ST_DOUBLE 3 + +#define ALPHA_LD_VOID 0 +#define ALPHA_LD_INT64 1 +#define ALPHA_LD_INT32 2 +#define ALPHA_LD_UINT16 3 +#define ALPHA_LD_SINT16 4 +#define ALPHA_LD_UINT8 5 +#define ALPHA_LD_SINT8 6 +#define ALPHA_LD_FLOAT 7 +#define ALPHA_LD_DOUBLE 8 + +#define ALPHA_ST_SHIFT 0 +#define ALPHA_LD_SHIFT 8 +#define ALPHA_RET_IN_MEM 0x10000 +#define ALPHA_FLAGS(S, L) (((L) << ALPHA_LD_SHIFT) | (S)) diff --git a/src/alpha/osf.S b/src/alpha/osf.S index 6b9f4df..fb9c595 100644 --- a/src/alpha/osf.S +++ b/src/alpha/osf.S @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------- - osf.S - Copyright (c) 1998, 2001, 2007, 2008, 2011 Red Hat - - Alpha/OSF Foreign Function Interface + osf.S - Copyright (c) 1998, 2001, 2007, 2008, 2011, 2014 Red Hat + + Alpha/OSF Foreign Function Interface Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the @@ -24,13 +24,21 @@ DEALINGS IN THE SOFTWARE. ----------------------------------------------------------------------- */ -#define LIBFFI_ASM +#define LIBFFI_ASM #include #include +#include +#include "internal.h" .arch ev6 .text +/* Aid in building a direct addressed jump table, 4 insns per entry. */ +.macro E index + .align 4 + .org 99b + \index * 16 +.endm + /* ffi_call_osf (void *args, unsigned long bytes, unsigned flags, void *raddr, void (*fnaddr)(void)); @@ -38,7 +46,7 @@ for this function. This has been allocated by ffi_call. We also deallocate some of the stack that has been alloca'd. */ - .align 3 + .align 4 .globl ffi_call_osf .ent ffi_call_osf FFI_HIDDEN(ffi_call_osf) @@ -46,15 +54,17 @@ ffi_call_osf: .frame $15, 32, $26, 0 .mask 0x4008000, -32 -$LFB1: + cfi_startproc addq $16,$17,$1 mov $16, $30 stq $26, 0($1) stq $15, 8($1) stq $18, 16($1) mov $1, $15 -$LCFI1: .prologue 0 + cfi_def_cfa($15, 32) + cfi_rel_offset($26, 0) + cfi_rel_offset($15, 8) stq $19, 24($1) mov $20, $27 @@ -77,71 +87,61 @@ $LCFI1: lda $30, 48($30) jsr $26, ($27), 0 - ldgp $29, 0($26) - - # If the return value pointer is NULL, assume no return value. - ldq $19, 24($15) - ldq $18, 16($15) +0: + ldah $29, 0($26) !gpdisp!1 + ldq $2, 24($15) + lda $29, 0($29) !gpdisp!1 + ldq $3, 16($15) + lda $1, 99f-0b($26) ldq $26, 0($15) -$LCFI2: - beq $19, $noretval - - # Store the return value out in the proper type. - cmpeq $18, FFI_TYPE_INT, $1 - bne $1, $retint - cmpeq $18, FFI_TYPE_FLOAT, $2 - bne $2, $retfloat - cmpeq $18, FFI_TYPE_DOUBLE, $3 - bne $3, $retdouble - - .align 3 -$noretval: ldq $15, 8($15) - ret + cfi_restore($26) + cfi_restore($15) + cfi_def_cfa($sp, 0) + cmoveq $2, ALPHA_ST_VOID, $3 # mash null return to void + addq $3, $3, $3 + s8addq $3, $1, $1 # 99f + stcode * 16 + jmp $31, ($1), $st_int .align 4 -$retint: - stq $0, 0($19) - nop - ldq $15, 8($15) +99: +E ALPHA_ST_VOID ret - - .align 4 -$retfloat: - sts $f0, 0($19) - nop - ldq $15, 8($15) +E ALPHA_ST_INT +$st_int: + stq $0, 0($2) ret - - .align 4 -$retdouble: - stt $f0, 0($19) - nop - ldq $15, 8($15) +E ALPHA_ST_FLOAT + sts $f0, 0($2) + ret +E ALPHA_ST_DOUBLE + stt $f0, 0($2) ret -$LFE1: + cfi_endproc .end ffi_call_osf /* ffi_closure_osf(...) Receives the closure argument in $1. */ - .align 3 +#define CLOSURE_FS (16*8) + + .align 4 .globl ffi_closure_osf .ent ffi_closure_osf FFI_HIDDEN(ffi_closure_osf) ffi_closure_osf: - .frame $30, 16*8, $26, 0 - .mask 0x4000000, -16*8 -$LFB2: + .frame $30, CLOSURE_FS, $26, 0 + .mask 0x4000000, -CLOSURE_FS + cfi_startproc ldgp $29, 0($27) - subq $30, 16*8, $30 -$LCFI5: + subq $30, CLOSURE_FS, $30 + cfi_adjust_cfa_offset(CLOSURE_FS) stq $26, 0($30) -$LCFI6: .prologue 1 + cfi_rel_offset($26, 0) # Store all of the potential argument registers in va_list format. stt $f16, 4*8($30) @@ -162,225 +162,74 @@ $LCFI6: lda $17, 2*8($30) lda $18, 10*8($30) jsr $26, ffi_closure_osf_inner - ldgp $29, 0($26) +0: + ldah $29, 0($26) !gpdisp!2 + lda $2, 99f-0b($26) + s4addq $0, 0, $1 # ldcode * 4 + ldq $0, 16($30) # preload return value + s4addq $1, $2, $1 # 99f + ldcode * 16 + lda $29, 0($29) !gpdisp!2 ldq $26, 0($30) - - # Load up the return value in the proper type. - lda $1, $load_table - s4addq $0, $1, $1 - ldl $1, 0($1) - addq $1, $29, $1 + cfi_restore($26) jmp $31, ($1), $load_32 - .align 4 -$load_none: - addq $30, 16*8, $30 +.macro epilogue + addq $30, CLOSURE_FS, $30 + cfi_adjust_cfa_offset(-CLOSURE_FS) ret + .align 4 + cfi_adjust_cfa_offset(CLOSURE_FS) +.endm .align 4 -$load_float: - lds $f0, 16($30) - nop - addq $30, 16*8, $30 - ret +99: +E ALPHA_LD_VOID + epilogue - .align 4 -$load_double: - ldt $f0, 16($30) - nop - addq $30, 16*8, $30 - ret +E ALPHA_LD_INT64 + epilogue - .align 4 -$load_u8: -#ifdef __alpha_bwx__ - ldbu $0, 16($30) - nop -#else - ldq $0, 16($30) - and $0, 255, $0 -#endif - addq $30, 16*8, $30 - ret - - .align 4 -$load_s8: -#ifdef __alpha_bwx__ - ldbu $0, 16($30) - sextb $0, $0 -#else - ldq $0, 16($30) - sll $0, 56, $0 - sra $0, 56, $0 -#endif - addq $30, 16*8, $30 - ret +E ALPHA_LD_INT32 +$load_32: + sextl $0, $0 + epilogue - .align 4 -$load_u16: -#ifdef __alpha_bwx__ - ldwu $0, 16($30) - nop -#else - ldq $0, 16($30) +E ALPHA_LD_UINT16 zapnot $0, 3, $0 -#endif - addq $30, 16*8, $30 - ret + epilogue - .align 4 -$load_s16: +E ALPHA_LD_SINT16 #ifdef __alpha_bwx__ - ldwu $0, 16($30) sextw $0, $0 #else - ldq $0, 16($30) sll $0, 48, $0 sra $0, 48, $0 #endif - addq $30, 16*8, $30 - ret + epilogue - .align 4 -$load_32: - ldl $0, 16($30) - nop - addq $30, 16*8, $30 - ret +E ALPHA_LD_UINT8 + and $0, 0xff, $0 + epilogue - .align 4 -$load_64: - ldq $0, 16($30) - nop - addq $30, 16*8, $30 - ret -$LFE2: - - .end ffi_closure_osf - -#ifdef __ELF__ -.section .rodata +E ALPHA_LD_SINT8 +#ifdef __alpha_bwx__ + sextb $0, $0 #else -.rdata -#endif -$load_table: - .gprel32 $load_none # FFI_TYPE_VOID - .gprel32 $load_32 # FFI_TYPE_INT - .gprel32 $load_float # FFI_TYPE_FLOAT - .gprel32 $load_double # FFI_TYPE_DOUBLE - .gprel32 $load_none # FFI_TYPE_LONGDOUBLE - .gprel32 $load_u8 # FFI_TYPE_UINT8 - .gprel32 $load_s8 # FFI_TYPE_SINT8 - .gprel32 $load_u16 # FFI_TYPE_UINT16 - .gprel32 $load_s16 # FFI_TYPE_SINT16 - .gprel32 $load_32 # FFI_TYPE_UINT32 - .gprel32 $load_32 # FFI_TYPE_SINT32 - .gprel32 $load_64 # FFI_TYPE_UINT64 - .gprel32 $load_64 # FFI_TYPE_SINT64 - .gprel32 $load_none # FFI_TYPE_STRUCT - .gprel32 $load_64 # FFI_TYPE_POINTER - -/* Assert that the table above is in sync with ffi.h. */ - -#if FFI_TYPE_FLOAT != 2 \ - || FFI_TYPE_DOUBLE != 3 \ - || FFI_TYPE_UINT8 != 5 \ - || FFI_TYPE_SINT8 != 6 \ - || FFI_TYPE_UINT16 != 7 \ - || FFI_TYPE_SINT16 != 8 \ - || FFI_TYPE_UINT32 != 9 \ - || FFI_TYPE_SINT32 != 10 \ - || FFI_TYPE_UINT64 != 11 \ - || FFI_TYPE_SINT64 != 12 \ - || FFI_TYPE_STRUCT != 13 \ - || FFI_TYPE_POINTER != 14 \ - || FFI_TYPE_LAST != 14 -#error "osf.S out of sync with ffi.h" + sll $0, 56, $0 + sra $0, 56, $0 #endif + epilogue -#ifdef __ELF__ -# define UA_SI .4byte -# define FDE_ENCODING 0x1b /* pcrel sdata4 */ -# define FDE_ENCODE(X) .4byte X-. -# define FDE_ARANGE(X) .4byte X -#elif defined __osf__ -# define UA_SI .align 0; .long -# define FDE_ENCODING 0x50 /* aligned absolute */ -# define FDE_ENCODE(X) .align 3; .quad X -# define FDE_ARANGE(X) .align 0; .quad X -#endif +E ALPHA_LD_FLOAT + lds $f0, 16($sp) + epilogue -#ifdef __ELF__ - .section .eh_frame,EH_FRAME_FLAGS,@progbits -#elif defined __osf__ - .data - .align 3 - .globl _GLOBAL__F_ffi_call_osf -_GLOBAL__F_ffi_call_osf: -#endif -__FRAME_BEGIN__: - UA_SI $LECIE1-$LSCIE1 # Length of Common Information Entry -$LSCIE1: - UA_SI 0x0 # CIE Identifier Tag - .byte 0x1 # CIE Version - .ascii "zR\0" # CIE Augmentation - .byte 0x1 # uleb128 0x1; CIE Code Alignment Factor - .byte 0x78 # sleb128 -8; CIE Data Alignment Factor - .byte 26 # CIE RA Column - .byte 0x1 # uleb128 0x1; Augmentation size - .byte FDE_ENCODING # FDE Encoding - .byte 0xc # DW_CFA_def_cfa - .byte 30 # uleb128 column 30 - .byte 0 # uleb128 offset 0 - .align 3 -$LECIE1: -$LSFDE1: - UA_SI $LEFDE1-$LASFDE1 # FDE Length -$LASFDE1: - UA_SI $LASFDE1-__FRAME_BEGIN__ # FDE CIE offset - FDE_ENCODE($LFB1) # FDE initial location - FDE_ARANGE($LFE1-$LFB1) # FDE address range - .byte 0x0 # uleb128 0x0; Augmentation size - - .byte 0x4 # DW_CFA_advance_loc4 - UA_SI $LCFI1-$LFB1 - .byte 0x9a # DW_CFA_offset, column 26 - .byte 4 # uleb128 4*-8 - .byte 0x8f # DW_CFA_offset, column 15 - .byte 0x3 # uleb128 3*-8 - .byte 0xc # DW_CFA_def_cfa - .byte 15 # uleb128 column 15 - .byte 32 # uleb128 offset 32 - - .byte 0x4 # DW_CFA_advance_loc4 - UA_SI $LCFI2-$LCFI1 - .byte 0xda # DW_CFA_restore, column 26 - .align 3 -$LEFDE1: - -$LSFDE3: - UA_SI $LEFDE3-$LASFDE3 # FDE Length -$LASFDE3: - UA_SI $LASFDE3-__FRAME_BEGIN__ # FDE CIE offset - FDE_ENCODE($LFB2) # FDE initial location - FDE_ARANGE($LFE2-$LFB2) # FDE address range - .byte 0x0 # uleb128 0x0; Augmentation size - - .byte 0x4 # DW_CFA_advance_loc4 - UA_SI $LCFI5-$LFB2 - .byte 0xe # DW_CFA_def_cfa_offset - .byte 0x80,0x1 # uleb128 128 - - .byte 0x4 # DW_CFA_advance_loc4 - UA_SI $LCFI6-$LCFI5 - .byte 0x9a # DW_CFA_offset, column 26 - .byte 16 # uleb128 offset 16*-8 - .align 3 -$LEFDE3: -#if defined __osf__ - .align 0 - .long 0 # End of Table -#endif +E ALPHA_LD_DOUBLE + ldt $f0, 16($sp) + epilogue + + cfi_endproc + .end ffi_closure_osf #if defined __ELF__ && defined __linux__ .section .note.GNU-stack,"",@progbits -- 1.9.3