OSDN Git Service

* src/sh/ffi.c (ffi_prep_closure): Set T bit in trampoline for
[pf3gnuchains/gcc-fork.git] / libffi / src / sh / ffi.c
index 8aa96a1..2045419 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------
-   ffi.c - Copyright (c) 2002, 2003 Kaz Kojima
+   ffi.c - Copyright (c) 2002, 2003, 2004 Kaz Kojima
    
    SuperH Foreign Function Interface 
 
@@ -471,16 +471,22 @@ ffi_prep_closure (ffi_closure* closure,
                  void *user_data)
 {
   unsigned int *tramp;
+  unsigned short insn;
 
   FFI_ASSERT (cif->abi == FFI_GCC_SYSV);
 
   tramp = (unsigned int *) &closure->tramp[0];
+  /* Set T bit if the function returns a struct pointed with R2.  */
+  insn = (return_type (cif->rtype) == FFI_TYPE_STRUCT
+         ? 0x0018 /* sett */
+         : 0x0008 /* clrt */);
+
 #ifdef __LITTLE_ENDIAN__
-  tramp[0] = 0xd301d202;
-  tramp[1] = 0x0009422b;
+  tramp[0] = 0xd301d102;
+  tramp[1] = 0x0000412b | (insn << 16);
 #else
-  tramp[0] = 0xd202d301;
-  tramp[1] = 0x422b0009;
+  tramp[0] = 0xd102d301;
+  tramp[1] = 0x412b0000 | insn;
 #endif
   *(void **) &tramp[2] = (void *)closure;          /* ctx */
   *(void **) &tramp[3] = (void *)ffi_closure_SYSV; /* funaddr */