This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

frv libffi port


This patch adds support to libffi for the FR-V architecture.  It support
both the regular EABI and the FDPIC variant used in uClinux and Linux. 
This includes full closure support.  

This patch includes two minor target independent changes. 
 - ffi_closure types are always aligned to 8-bytes,
 - and a new ALIGN_DOWN macro is introduced.
It also adds a configure.host for platform specific options.  frv-elf
requires this to pick up the right libgloss bits.

Tested on frv-elf with zero failures on the libffi testsuite for all
multilibs.   I am checking it in, although I am not enabling it in the
top level configure file.

2004-08-30  Anthony Green  <green@redhat.com>
 
        * Makefile.am: Add frv support.
        * Makefile.in, testsuite/Makefile.in: Rebuilt.
        * configure.ac: Read configure.host.
	* configure, aclocal.m4: Rebuilt.
        * configure.host: New file.  frv-elf needs libgloss.
        * include/ffi.h.in: Force ffi_closure to have a nice big (8)
        alignment.  This is needed to frv and should harm the others.
        * include/ffi_common.h (ALIGN_DOWN): New macro.
        * src/frv/ffi.c, src/frv/ffitarget.h, src/frv/eabi.S: New files.
 
Index: Makefile.am
===================================================================
RCS file: /cvs/gcc/gcc/libffi/Makefile.am,v
retrieving revision 1.34
diff -p -r1.34 Makefile.am
*** Makefile.am	17 Jun 2004 21:32:58 -0000	1.34
--- Makefile.am	30 Aug 2004 15:18:56 -0000
*************** EXTRA_DIST = LICENSE ChangeLog.v1 \
*** 23,29 ****
  	src/sparc/ffi.c \
  	src/x86/ffi.c src/x86/sysv.S src/x86/win32.S \
  	src/x86/ffi64.c src/x86/unix64.S src/x86/ffitarget.h \
! 	src/pa/ffi.c src/pa/linux.S
  
  ## ################################################################
  
--- 23,29 ----
  	src/sparc/ffi.c \
  	src/x86/ffi.c src/x86/sysv.S src/x86/win32.S \
  	src/x86/ffi64.c src/x86/unix64.S src/x86/ffitarget.h \
! 	src/pa/ffi.c src/pa/linux.S src/frv/eabi.S src/frv/ffitarget.h
  
  ## ################################################################
  
*************** endif
*** 116,121 ****
--- 116,124 ----
  if ARM
  nodist_libffi_la_SOURCES += src/arm/sysv.S src/arm/ffi.c
  endif
+ if FRV
+ nodist_libffi_la_SOURCES += src/frv/eabi.S src/frv/ffi.c
+ endif
  if S390
  nodist_libffi_la_SOURCES += src/s390/sysv.S src/s390/ffi.c
  endif
Index: configure.ac
===================================================================
RCS file: /cvs/gcc/gcc/libffi/configure.ac,v
retrieving revision 1.6
diff -p -r1.6 configure.ac
*** configure.ac	3 Aug 2004 20:48:48 -0000	1.6
--- configure.ac	30 Aug 2004 15:18:59 -0000
*************** AM_ENABLE_MULTILIB(, ..)
*** 10,15 ****
--- 10,17 ----
  AC_CANONICAL_SYSTEM
  target_alias=${target_alias-$host_alias}
  
+ . ${srcdir}/configure.host
+ 
  AM_INIT_AUTOMAKE
  
  # The same as in boehm-gc and libstdc++. Have to borrow it from there.
*************** i*86-*-netbsdelf* | i*86-*-knetbsd*-gnu)
*** 47,52 ****
--- 49,55 ----
  i*86-*-win32*) TARGET=X86_WIN32; TARGETDIR=x86;;
  i*86-*-cygwin*) TARGET=X86_WIN32; TARGETDIR=x86;;
  i*86-*-mingw*) TARGET=X86_WIN32; TARGETDIR=x86;;
+ frv-*-*) TARGET=FRV; TARGETDIR=frv;;
  sparc-sun-4*) TARGET=SPARC; TARGETDIR=sparc;;
  sparc*-sun-*) TARGET=SPARC; TARGETDIR=sparc;;
  sparc-*-linux* | sparc-*-netbsdelf* | sparc-*-knetbsd*-gnu) TARGET=SPARC; TARGETDIR=sparc;;
*************** AM_CONDITIONAL(POWERPC, test x$TARGET = 
*** 90,95 ****
--- 93,99 ----
  AM_CONDITIONAL(POWERPC_AIX, test x$TARGET = xPOWERPC_AIX)
  AM_CONDITIONAL(POWERPC_DARWIN, test x$TARGET = xPOWERPC_DARWIN)
  AM_CONDITIONAL(ARM, test x$TARGET = xARM)
+ AM_CONDITIONAL(FRV, test x$TARGET = xFRV)
  AM_CONDITIONAL(S390, test x$TARGET = xS390)
  AM_CONDITIONAL(X86_64, test x$TARGET = xX86_64)
  AM_CONDITIONAL(SH, test x$TARGET = xSH)
Index: configure.host
===================================================================
RCS file: configure.host
diff -N configure.host
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- configure.host	30 Aug 2004 15:18:59 -0000
***************
*** 0 ****
--- 1,11 ----
+ # configure.host
+ #
+ # This shell script handles all host based configuration for libffi.
+ # 
+ 
+ # THIS TABLE IS SORTED.  KEEP IT THAT WAY.
+ case "${host}" in
+   frv*-elf)
+     LDFLAGS=`echo $LDFLAGS | sed "s/\-B[^ ]*libgloss\/frv\///"`\ -B`pwd`/../libgloss/frv/
+     ;;
+ esac
Index: include/ffi.h.in
===================================================================
RCS file: /cvs/gcc/gcc/libffi/include/ffi.h.in,v
retrieving revision 1.28
diff -p -r1.28 ffi.h.in
*** include/ffi.h.in	21 Oct 2003 19:01:53 -0000	1.28
--- include/ffi.h.in	30 Aug 2004 15:18:59 -0000
*************** typedef struct {
*** 218,224 ****
    ffi_cif   *cif;
    void     (*fun)(ffi_cif*,void*,void**,void*);
    void      *user_data;
! } ffi_closure;
  
  ffi_status
  ffi_prep_closure (ffi_closure*,
--- 218,224 ----
    ffi_cif   *cif;
    void     (*fun)(ffi_cif*,void*,void**,void*);
    void      *user_data;
! } ffi_closure __attribute__((aligned (8)));
  
  ffi_status
  ffi_prep_closure (ffi_closure*,
Index: include/ffi_common.h
===================================================================
RCS file: /cvs/gcc/gcc/libffi/include/ffi_common.h,v
retrieving revision 1.2
diff -p -r1.2 ffi_common.h
*** include/ffi_common.h	21 Oct 2003 19:01:53 -0000	1.2
--- include/ffi_common.h	30 Aug 2004 15:18:59 -0000
*************** void ffi_type_test(/*@temp@*/ /*@out@*/ 
*** 60,65 ****
--- 60,66 ----
  #endif
  
  #define ALIGN(v, a)  (((((size_t) (v))-1) | ((a)-1))+1)
+ #define ALIGN_DOWN(v, a) (((size_t) (v)) & -a)
  
  /* Perform machine dependent cif processing */
  ffi_status ffi_prep_cif_machdep(ffi_cif *cif);
Index: src/frv/eabi.S
===================================================================
RCS file: src/frv/eabi.S
diff -N src/frv/eabi.S
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- src/frv/eabi.S	30 Aug 2004 15:18:59 -0000
***************
*** 0 ****
--- 1,130 ----
+ /* -----------------------------------------------------------------------
+    eabi.S - Copyright (c) 2004  Anthony Green
+    
+    FR-V Assembly glue.
+ 
+    $Id: sysv.S,v 1.1.1.1 1998/11/29 16:48:16 green Exp $
+ 
+    Permission is hereby granted, free of charge, to any person obtaining
+    a copy of this software and associated documentation files (the
+    ``Software''), to deal in the Software without restriction, including
+    without limitation the rights to use, copy, modify, merge, publish,
+    distribute, sublicense, and/or sell copies of the Software, and to
+    permit persons to whom the Software is furnished to do so, subject to
+    the following conditions:
+ 
+    The above copyright notice and this permission notice shall be included
+    in all copies or substantial portions of the Software.
+ 
+    THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+    IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
+    OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+    ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+    OTHER DEALINGS IN THE SOFTWARE.
+    ----------------------------------------------------------------------- */
+ 
+ #define LIBFFI_ASM	
+ #include <fficonfig.h>
+ #include <ffi.h>
+ 
+ 	.globl ffi_prep_args_EABI
+ 
+ 	.text
+ 	.p2align 4
+ 	.globl ffi_call_EABI
+ 	.type ffi_call_EABI, @function
+ 
+ 	# gr8 :   ffi_prep_args
+ 	# gr9 :   &ecif
+ 	# gr10:   cif->bytes
+ 	# gr11:   fig->flags
+ 	# gr12:   ecif.rvalue
+ 	# gr13:   fn
+ 	
+ ffi_call_EABI:	
+ 	addi	sp, #-80, sp
+ 	sti	fp, @(sp, #24)
+ 	addi	sp, #24, fp
+ 	movsg	lr, gr5
+ 
+ 	/* Make room for the new arguments.  */
+ 	/* subi	sp, fp, gr10 */
+ 	
+ 	/* Store return address and incoming args on stack.  */
+ 	sti	gr5, @(fp, #8)
+ 	sti	gr8, @(fp, #-4)
+ 	sti	gr9, @(fp, #-8)
+ 	sti	gr10, @(fp, #-12)
+ 	sti	gr11, @(fp, #-16)
+ 	sti	gr12, @(fp, #-20)
+ 	sti	gr13, @(fp, #-24)
+ 
+ 	sub     sp, gr10, sp
+ 	
+ 	/* Call ffi_prep_args.  */
+ 	ldi	@(fp, #-4), gr4
+ 	addi	sp, #0, gr8
+ 	ldi	@(fp, #-8), gr9
+ #ifdef __FRV_FDPIC__
+ 	ldd	@(gr4, gr0), gr14
+ 	calll	@(gr14, gr0)
+ #else
+ 	calll	@(gr4, gr0)
+ #endif	
+ 
+ 	/* ffi_prep_args returns the new stack pointer.  */
+ 	mov	gr8, gr4
+ 		
+ 	ldi	@(sp, #0), gr8
+ 	ldi	@(sp, #4), gr9
+ 	ldi	@(sp, #8), gr10
+ 	ldi	@(sp, #12), gr11
+ 	ldi	@(sp, #16), gr12
+ 	ldi	@(sp, #20), gr13
+ 
+ 	/* Always copy the return value pointer into the hidden
+ 	   parameter register.  This is only strictly necessary
+ 	   when we're returning an aggregate type, but it doesn't
+ 	   hurt to do this all the time, and it saves a branch.  */
+ 	ldi	@(fp, #-20), gr3
+ 
+ 	/* Use the ffi_prep_args return value for the new sp.  */
+ 	mov	gr4, sp
+ 	
+ 	/* Call the target function.  */
+ 	ldi	@(fp, -24), gr4
+ #ifdef __FRV_FDPIC__
+ 	ldd	@(gr4, gr0), gr14
+ 	calll	@(gr14, gr0)
+ #else
+ 	calll	@(gr4, gr0)
+ #endif	
+ 
+ 	/* Store the result. */
+ 	ldi	@(fp, #-16), gr10  /* fig->flags */
+ 	ldi	@(fp, #-20), gr4   /* ecif.rvalue */
+ 
+ 	/* Is the return value stored in two registers?  */
+ 	cmpi	gr10, #8, icc0
+ 	bne	icc0, 0, .L2
+ 	/*   Yes, save them.  */
+ 	sti	gr8, @(gr4, #0)
+ 	sti	gr9, @(gr4, #4)
+ 	bra	.L3
+ .L2:
+ 	/* Is the return value a structure?  */
+ 	cmpi	gr10, #-1, icc0
+ 	beq	icc0, 0, .L3
+ 	/*   No, save a 4 byte return value.  */
+ 	sti	gr8, @(gr4, #0)
+ .L3:	
+ 
+ 	/* Restore the stack, and return.  */
+ 	ldi	@(fp, 8), gr5
+ 	ld	@(fp, gr0), fp
+ 	addi	sp,#80,sp
+ 	jmpl	@(gr5,gr0)
+ 	.size ffi_call_EABI, .-ffi_call_EABI
+ 	
Index: src/frv/ffi.c
===================================================================
RCS file: src/frv/ffi.c
diff -N src/frv/ffi.c
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- src/frv/ffi.c	30 Aug 2004 15:18:59 -0000
***************
*** 0 ****
--- 1,287 ----
+ /* -----------------------------------------------------------------------
+    ffi.c - Copyright (c) 2004  Anthony Green
+    
+    FR-V Foreign Function Interface 
+ 
+    Permission is hereby granted, free of charge, to any person obtaining
+    a copy of this software and associated documentation files (the
+    ``Software''), to deal in the Software without restriction, including
+    without limitation the rights to use, copy, modify, merge, publish,
+    distribute, sublicense, and/or sell copies of the Software, and to
+    permit persons to whom the Software is furnished to do so, subject to
+    the following conditions:
+ 
+    The above copyright notice and this permission notice shall be included
+    in all copies or substantial portions of the Software.
+ 
+    THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+    IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
+    OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+    ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+    OTHER DEALINGS IN THE SOFTWARE.
+    ----------------------------------------------------------------------- */
+ 
+ #include <ffi.h>
+ #include <ffi_common.h>
+ 
+ #include <stdlib.h>
+ 
+ /* ffi_prep_args is called by the assembly routine once stack space
+    has been allocated for the function's arguments */
+ 
+ void *ffi_prep_args(char *stack, extended_cif *ecif)
+ {
+   register unsigned int i;
+   register void **p_argv;
+   register char *argp;
+   register ffi_type **p_arg;
+   register int count = 0;
+ 
+   p_argv = ecif->avalue;
+   argp = stack;
+ 
+   for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
+        (i != 0);
+        i--, p_arg++)
+     {
+       size_t z;
+       
+       z = (*p_arg)->size;
+ 
+       if ((*p_arg)->type == FFI_TYPE_STRUCT)
+ 	{
+ 	  z = sizeof(void*);
+ 	  *(void **) argp = *p_argv;
+ 	} 
+       /*      if ((*p_arg)->type == FFI_TYPE_FLOAT)
+ 	{
+ 	  if (count > 24)
+ 	    {
+ 	      // This is going on the stack.  Turn it into a double.  
+ 	      *(double *) argp = (double) *(float*)(* p_argv);
+ 	      z = sizeof(double);
+ 	    }
+ 	  else
+ 	    *(void **) argp = *(void **)(* p_argv);
+ 	}  */
+       else if (z < sizeof(int))
+ 	{
+ 	  z = sizeof(int);
+ 	  switch ((*p_arg)->type)
+ 	    {
+ 	    case FFI_TYPE_SINT8:
+ 	      *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
+ 	      break;
+ 	      
+ 	    case FFI_TYPE_UINT8:
+ 	      *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
+ 	      break;
+ 	      
+ 	    case FFI_TYPE_SINT16:
+ 	      *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
+ 	      break;
+ 		  
+ 	    case FFI_TYPE_UINT16:
+ 	      *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
+ 	      break;
+ 		  
+ 	    default:
+ 	      FFI_ASSERT(0);
+ 	    }
+ 	}
+       else if (z == sizeof(int))
+ 	{
+ 	  *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+ 	}
+       else
+ 	{
+ 	  memcpy(argp, *p_argv, z);
+ 	}
+       p_argv++;
+       argp += z;
+       count += z;
+     }
+ 
+   return (stack + ((count > 24) ? 24 : ALIGN_DOWN(count, 8)));
+ }
+ 
+ /* Perform machine dependent cif processing */
+ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+ {
+   if (cif->rtype->type == FFI_TYPE_STRUCT)
+     cif->flags = -1;
+   else
+     cif->flags = cif->rtype->size;
+ 
+   cif->bytes = ALIGN (cif->bytes, 8);
+ 
+   return FFI_OK;
+ }
+ 
+ extern void ffi_call_EABI(void *(*)(char *, extended_cif *), 
+ 			  extended_cif *, 
+ 			  unsigned, unsigned, 
+ 			  unsigned *, 
+ 			  void (*fn)());
+ 
+ void ffi_call(ffi_cif *cif, 
+ 	      void (*fn)(), 
+ 	      void *rvalue, 
+ 	      void **avalue)
+ {
+   extended_cif ecif;
+ 
+   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 ((rvalue == NULL) && 
+       (cif->rtype->type == FFI_TYPE_STRUCT))
+     {
+       ecif.rvalue = alloca(cif->rtype->size);
+     }
+   else
+     ecif.rvalue = rvalue;
+     
+   
+   switch (cif->abi) 
+     {
+     case FFI_EABI:
+       ffi_call_EABI(ffi_prep_args, &ecif, cif->bytes, 
+ 		    cif->flags, ecif.rvalue, fn);
+       break;
+     default:
+       FFI_ASSERT(0);
+       break;
+     }
+ }
+ 
+ void ffi_closure_eabi (unsigned arg1, unsigned arg2, unsigned arg3,
+ 		       unsigned arg4, unsigned arg5, unsigned arg6)
+ {
+   /* This function is called by a trampoline.  The trampoline stows a
+      pointer to the ffi_closure object in gr7.  We must save this
+      pointer in a place that will persist while we do our work.  */
+   register ffi_closure *creg __asm__ ("gr7");
+   ffi_closure *closure = creg;
+ 
+   /* Arguments that don't fit in registers are found on the stack
+      at a fixed offset above the current frame pointer.  */
+   register char *frame_pointer __asm__ ("fp");
+   char *stack_args = frame_pointer + 16;
+ 
+   /* Lay the register arguments down in a continuous chunk of memory.  */
+   unsigned register_args[6] =
+     { arg1, arg2, arg3, arg4, arg5, arg6 };
+ 
+   ffi_cif *cif = closure->cif;
+   ffi_type **arg_types = cif->arg_types;
+   void **avalue = alloca (cif->nargs * sizeof(void *));
+   char *ptr = (char *) register_args;
+   int i;
+ 
+   /* Find the address of each argument.  */
+   for (i = 0; i < cif->nargs; i++)
+     {
+       switch (arg_types[i]->type)
+ 	{
+ 	case FFI_TYPE_SINT8:
+ 	case FFI_TYPE_UINT8:
+ 	  avalue[i] = ptr + 3;
+ 	  break;
+ 	case FFI_TYPE_SINT16:
+ 	case FFI_TYPE_UINT16:
+ 	  avalue[i] = ptr + 2;
+ 	  break;
+ 	case FFI_TYPE_SINT32:
+ 	case FFI_TYPE_UINT32:
+ 	case FFI_TYPE_FLOAT:
+ 	  avalue[i] = ptr;
+ 	  break;
+ 	case FFI_TYPE_STRUCT:
+ 	  avalue[i] = *(void**)ptr;
+ 	  break;
+ 	default:
+ 	  /* This is an 8-byte value.  */
+ 	  avalue[i] = ptr;
+ 	  ptr += 4;
+ 	  break;
+ 	}
+       ptr += 4;
+ 
+       /* If we've handled more arguments than fit in registers,
+ 	 start looking at the those passed on the stack.  */
+       if (ptr == ((char *)register_args + (6*4)))
+ 	ptr = stack_args;
+     }
+ 
+   /* Invoke the closure.  */
+   if (cif->rtype->type == FFI_TYPE_STRUCT)
+     {
+       /* The caller allocates space for the return structure, and
+        passes a pointer to this space in gr3.  Use this value directly
+        as the return value.  */
+       register void *return_struct_ptr __asm__("gr3");
+       (closure->fun) (cif, return_struct_ptr, avalue, closure->user_data);
+     }
+   else
+     {
+       /* Allocate space for the return value and call the function.  */
+       long long rvalue;
+       (closure->fun) (cif, &rvalue, avalue, closure->user_data);
+ 
+       /* Functions return 4-byte or smaller results in gr8.  8-byte
+ 	 values also use gr9.  We fill the both, even for small return
+ 	 values, just to avoid a branch.  */ 
+       asm ("ldi  @(%0, #0), gr8" : : "r" (&rvalue));
+       asm ("ldi  @(%0, #0), gr9" : : "r" (&((int *) &rvalue)[1]));
+     }
+ }
+ 
+ ffi_status
+ ffi_prep_closure (ffi_closure* closure,
+ 		  ffi_cif* cif,
+ 		  void (*fun)(ffi_cif*, void*, void**, void*),
+ 		  void *user_data)
+ {
+   unsigned int *tramp = (unsigned int *) &closure->tramp[0];
+   unsigned long fn = (long) ffi_closure_eabi;
+   unsigned long cls = (long) closure;
+ #ifdef __FRV_FDPIC__
+   register void *got __asm__("gr15");
+ #endif
+   int i;
+ 
+   fn = (unsigned long) ffi_closure_eabi;
+ 
+ #ifdef __FRV_FDPIC__
+   tramp[0] = &tramp[2];
+   tramp[1] = got;
+   tramp[2] = 0x8cfc0000 + (fn  & 0xffff); /* setlos lo(fn), gr6    */
+   tramp[3] = 0x8efc0000 + (cls & 0xffff); /* setlos lo(cls), gr7   */
+   tramp[4] = 0x8cf80000 + (fn  >> 16);	  /* sethi hi(fn), gr6     */
+   tramp[5] = 0x8ef80000 + (cls >> 16);    /* sethi hi(cls), gr7    */
+   tramp[6] = 0x9cc86000;                  /* ldi @(gr6, #0), gr14  */
+   tramp[7] = 0x8030e000;                  /* jmpl @(gr14, gr0)     */
+ #else
+   tramp[0] = 0x8cfc0000 + (fn  & 0xffff); /* setlos lo(fn), gr6    */
+   tramp[1] = 0x8efc0000 + (cls & 0xffff); /* setlos lo(cls), gr7   */
+   tramp[2] = 0x8cf80000 + (fn  >> 16);	  /* sethi hi(fn), gr6     */
+   tramp[3] = 0x8ef80000 + (cls >> 16);    /* sethi hi(cls), gr7    */
+   tramp[4] = 0x80300006;                  /* jmpl @(gr0, gr6)      */
+ #endif
+ 
+   closure->cif = cif;
+   closure->fun = fun;
+   closure->user_data = user_data;
+ 
+   /* Cache flushing.  */
+   for (i = 0; i < FFI_TRAMPOLINE_SIZE; i++)
+     __asm__ volatile ("dcf @(%0,%1)\n\tici @(%0,%1)" :: "r" (tramp), "r" (i));
+ 
+   return FFI_OK;
+ }
Index: src/frv/ffitarget.h
===================================================================
RCS file: src/frv/ffitarget.h
diff -N src/frv/ffitarget.h
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- src/frv/ffitarget.h	30 Aug 2004 15:18:59 -0000
***************
*** 0 ****
--- 1,88 ----
+ /* -----------------------------------------------------------------*-C-*-
+    ffitarget.h - Copyright (c) 1996-2004  Red Hat, Inc.
+    Target configuration macros for FR-V
+ 
+    Permission is hereby granted, free of charge, to any person obtaining
+    a copy of this software and associated documentation files (the
+    ``Software''), to deal in the Software without restriction, including
+    without limitation the rights to use, copy, modify, merge, publish,
+    distribute, sublicense, and/or sell copies of the Software, and to
+    permit persons to whom the Software is furnished to do so, subject to
+    the following conditions:
+ 
+    The above copyright notice and this permission notice shall be included
+    in all copies or substantial portions of the Software.
+ 
+    THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+    IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
+    OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+    ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+    OTHER DEALINGS IN THE SOFTWARE.
+ 
+    ----------------------------------------------------------------------- */
+ 
+ #ifndef LIBFFI_TARGET_H
+ #define LIBFFI_TARGET_H
+ 
+ /* ---- System specific configurations ----------------------------------- */
+ 
+ #if defined (POWERPC) && defined (__powerpc64__)
+ #define POWERPC64
+ #endif
+ 
+ #ifndef LIBFFI_ASM
+ typedef unsigned long          ffi_arg;
+ typedef signed long            ffi_sarg;
+ 
+ typedef enum ffi_abi {
+   FFI_FIRST_ABI = 0,
+ 
+ #ifdef FRV
+   FFI_EABI,
+   FFI_DEFAULT_ABI = FFI_EABI,
+ #endif
+ 
+ #ifdef POWERPC
+   FFI_SYSV,
+   FFI_GCC_SYSV,
+   FFI_LINUX64,
+ # ifdef POWERPC64
+   FFI_DEFAULT_ABI = FFI_LINUX64,
+ # else
+   FFI_DEFAULT_ABI = FFI_GCC_SYSV,
+ # endif
+ #endif
+ 
+ #ifdef POWERPC_AIX
+   FFI_AIX,
+   FFI_DARWIN,
+   FFI_DEFAULT_ABI = FFI_AIX,
+ #endif
+ 
+ #ifdef POWERPC_DARWIN
+   FFI_AIX,
+   FFI_DARWIN,
+   FFI_DEFAULT_ABI = FFI_DARWIN,
+ #endif
+ 
+   FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
+ } ffi_abi;
+ #endif
+ 
+ /* ---- Definitions for closures ----------------------------------------- */
+ 
+ #define FFI_CLOSURES 1
+ #define FFI_NATIVE_RAW_API 0
+ 
+ #ifdef __FRV_FDPIC__
+ /* Trampolines are 8 4-byte instructions long.  */
+ #define FFI_TRAMPOLINE_SIZE (8*4) 
+ #else
+ /* Trampolines are 5 4-byte instructions long.  */
+ #define FFI_TRAMPOLINE_SIZE (5*4) 
+ #endif
+ 
+ #endif
+ 




-- 
Anthony Green <green@redhat.com>
Red Hat, Inc.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]