public inbox for java-prs@sourceware.org
help / color / mirror / Atom feed
From: "ktietz70 at googlemail dot com" <gcc-bugzilla@gcc.gnu.org>
To: java-prs@gcc.gnu.org
Subject: [Bug libgcj/51500] [4.7 regression] 106 unexpected libjava testsuite failures with mingw32
Date: Tue, 31 Jan 2012 09:47:00 -0000	[thread overview]
Message-ID: <bug-51500-8172-sDx1FaPtjc@http.gcc.gnu.org/bugzilla/> (raw)
In-Reply-To: <bug-51500-8172@http.gcc.gnu.org/bugzilla/>

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51500

--- Comment #17 from ktietz70 at googlemail dot com 2012-01-31 09:47:08 UTC ---
Ok, here is a variant treating stack-alignment for closure.

ChangeLog

2012-01-31  Kai Tietz  <ktietz@redhat.com>

    * src/prep_cif.c (ffi_prep_cif): Allow for X86_WIN32
    also FFI_THISCALL.
    * src/x86/ffi.c (ffi_closure_THISCALL): Add prototype.
    (FFI_INIT_TRAMPOLINE_THISCALL): New trampoline code.
    (ffi_prep_closure_loc): Add FFI_THISCALL support.
    * src/x86/ffitarget.h (FFI_TRAMPOLINE_SIZE): Adjust size.
    * src/x86/win32.S (ffi_closure_THISCALL): New closure code
    for thiscall-calling convention.
    * testsuite/libffi.call/closure_thiscall.c: New test.

Index: gcc/libffi/src/prep_cif.c
===================================================================
--- gcc.orig/libffi/src/prep_cif.c
+++ gcc/libffi/src/prep_cif.c
@@ -93,7 +93,12 @@ ffi_status ffi_prep_cif(ffi_cif *cif, ff
   ffi_type **ptr;

   FFI_ASSERT(cif != NULL);
+#ifndef X86_WIN32
   FFI_ASSERT((abi > FFI_FIRST_ABI) && (abi <= FFI_DEFAULT_ABI));
+#else
+  FFI_ASSERT(abi > FFI_FIRST_ABI && abi <= FFI_DEFAULT_ABI
+         || abi == FFI_THISCALL);
+#endif

   cif->abi = abi;
   cif->arg_types = atypes;
Index: gcc/libffi/src/x86/ffi.c
===================================================================
--- gcc.orig/libffi/src/x86/ffi.c
+++ gcc/libffi/src/x86/ffi.c
@@ -449,6 +449,8 @@ void FFI_HIDDEN ffi_closure_raw_SYSV (ff
 #ifdef X86_WIN32
 void FFI_HIDDEN ffi_closure_STDCALL (ffi_closure *)
      __attribute__ ((regparm(1)));
+void FFI_HIDDEN ffi_closure_THISCALL (ffi_closure *)
+     __attribute__ ((regparm(1)));
 #endif
 #ifdef X86_WIN64
 void FFI_HIDDEN ffi_closure_win64 (ffi_closure *);
@@ -608,6 +610,33 @@ ffi_prep_incoming_args_SYSV(char *stack,
    *(unsigned int*)  &__tramp[6] = __dis; /* jmp __fun  */ \
  }

+#define FFI_INIT_TRAMPOLINE_THISCALL(TRAMP,FUN,CTX,SIZE) \
+{ unsigned char *__tramp = (unsigned char*)(TRAMP); \
+   unsigned int  __fun = (unsigned int)(FUN); \
+   unsigned int  __ctx = (unsigned int)(CTX); \
+   unsigned int  __dis = __fun - (__ctx + 22);  \
+   unsigned short __size = (unsigned short)(SIZE); \
+   *(unsigned int *) &__tramp[0] = 0x8324048b;    /* mov (%esp), %eax */ \
+   *(unsigned int *) &__tramp[4] = 0x4c8910ec;    /* sub $16, %esp */ \
+   *(unsigned int *) &__tramp[8] = 0x04890424;    /* mov %ecx, 4(%esp) */ \
+   *(unsigned char*) &__tramp[12] = 0x24;    /* mov %eax, (%esp) */ \
+   *(unsigned char*) &__tramp[13] = 0xb8; \
+   *(unsigned int *) &__tramp[14] = __size;    /* mov __size, %eax */ \
+   *(unsigned int *) &__tramp[18] = 0x08244c8d;    /* lea 8(%esp), %ecx */ \
+   *(unsigned int *) &__tramp[22] = 0x4802e8c1; /* shr $2, %eax ; dec %eax */
\
+   *(unsigned short*) &__tramp[26] = 0x0b74;    /* jz 1f */ \
+   *(unsigned int *) &__tramp[28] = 0x890c518b;    /* 2b: mov 12(%eax), %edx
*/ \
+   *(unsigned int *) &__tramp[32] = 0x04c18311; /* mov %edx, (%ecx) ;
add $4, %edx */ \
+   *(unsigned char*) &__tramp[36] = 0x48;    /* dec %eax */ \
+   *(unsigned short*) &__tramp[37] = 0xf575;    /* jnz 2b ; 1f: */ \
+   *(unsigned char*) &__tramp[39] = 0xb8; \
+   *(unsigned int*)  &__tramp[40] = __ctx; /* movl __ctx, %eax */ \
+   *(unsigned char *)  &__tramp[44] = 0xe8; \
+   *(unsigned int*)  &__tramp[45] = __dis; /* call __fun  */ \
+   *(unsigned char*)  &__tramp[49] = 0xc2; /* ret  */ \
+   *(unsigned short*)  &__tramp[50] = (__size + 12); /* ret (__size + 12)  */
\
+ }
+
 #define FFI_INIT_TRAMPOLINE_STDCALL(TRAMP,FUN,CTX,SIZE)  \
 { unsigned char *__tramp = (unsigned char*)(TRAMP); \
    unsigned int  __fun = (unsigned int)(FUN); \
@@ -650,6 +679,13 @@ ffi_prep_closure_loc (ffi_closure* closu
                            (void*)codeloc);
     }
 #ifdef X86_WIN32
+  else if (cif->abi == FFI_THISCALL)
+    {
+      FFI_INIT_TRAMPOLINE_THISCALL (&closure->tramp[0],
+                    &ffi_closure_THISCALL,
+                    (void*)codeloc,
+                    cif->bytes);
+    }
   else if (cif->abi == FFI_STDCALL)
     {
       FFI_INIT_TRAMPOLINE_STDCALL (&closure->tramp[0],
Index: gcc/libffi/src/x86/ffitarget.h
===================================================================
--- gcc.orig/libffi/src/x86/ffitarget.h
+++ gcc/libffi/src/x86/ffitarget.h
@@ -103,7 +103,7 @@ typedef enum ffi_abi {
 #define FFI_NATIVE_RAW_API 0
 #else
 #ifdef X86_WIN32
-#define FFI_TRAMPOLINE_SIZE 13
+#define FFI_TRAMPOLINE_SIZE 52
 #else
 #ifdef X86_WIN64
 #define FFI_TRAMPOLINE_SIZE 29
Index: gcc/libffi/src/x86/win32.S
===================================================================
--- gcc.orig/libffi/src/x86/win32.S
+++ gcc/libffi/src/x86/win32.S
@@ -170,6 +170,16 @@ ca_epilogue:
         ret
 ffi_call_win32 ENDP

+ffi_closure_THISCALL PROC NEAR FORCEFRAME
+    push    ebp
+    mov    ebp, esp
+    sub    esp, 40
+    lea    edx, [ebp -24]
+    mov    [ebp - 12], edx    /* resp */
+    lea    edx, [ebp + 12]  /* account for stub return address on stack */
+    jmp    stub
+ffi_closure_THISCALL ENDP
+
 ffi_closure_SYSV PROC NEAR FORCEFRAME
     ;; the ffi_closure ctx is passed in eax by the trampoline.

@@ -177,6 +187,7 @@ ffi_closure_SYSV PROC NEAR FORCEFRAME
         lea  edx, [ebp - 24]
         mov  [ebp - 12], edx         ;; resp
         lea  edx, [ebp + 8]
+stub:
         mov  [esp + 8], edx          ;; args
         lea  edx, [ebp - 12]
         mov  [esp + 4], edx          ;; &resp
@@ -573,6 +584,19 @@ _ffi_call_win32:
         popl %ebp
         ret
 .ffi_call_win32_end:
+        .balign 16
+    .globl    _ffi_closure_THISCALL
+#ifndef __OS2__
+    .def    _ffi_closure_THISCALL;    .scl    2;    .type    32;    .endef
+#endif
+_ffi_closure_THISCALL:
+    pushl    %ebp
+    movl    %esp, %ebp
+    subl    $40, %esp
+    leal    -24(%ebp), %edx
+    movl    %edx, -12(%ebp)    /* resp */
+    leal    12(%ebp), %edx  /* account for stub return address on stack */
+    jmp    .stub
 .LFE1:

         # This assumes we are using gas.
@@ -591,6 +615,7 @@ _ffi_closure_SYSV:
     leal    -24(%ebp), %edx
     movl    %edx, -12(%ebp)    /* resp */
     leal    8(%ebp), %edx
+.stub:
     movl    %edx, 4(%esp)    /* args = __builtin_dwarf_cfa () */
     leal    -12(%ebp), %edx
     movl    %edx, (%esp)    /* &resp */
Index: gcc/libffi/testsuite/libffi.call/closure_thiscall.c
===================================================================
--- /dev/null
+++ gcc/libffi/testsuite/libffi.call/closure_thiscall.c
@@ -0,0 +1,64 @@
+/* Area:    closure_call (thiscall convention)
+   Purpose:    Check handling when caller expects thiscall callee
+   Limitations:    none.
+   PR:        none.
+   Originator:    <ktietz@redhat.com> */
+
+/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */
+#include "ffitest.h"
+
+static void
+closure_test_thiscall(ffi_cif* cif __UNUSED__, void* resp, void** args,
+              void* userdata)
+{
+  *(ffi_arg*)resp =
+    (int)*(int *)args[0] + (int)(*(int *)args[1])
+    + (int)(*(int *)args[2])  + (int)(*(int *)args[3])
+    + (int)(intptr_t)userdata;
+
+  printf("%d %d %d %d: %d\n",
+     (int)*(int *)args[0], (int)(*(int *)args[1]),
+     (int)(*(int *)args[2]), (int)(*(int *)args[3]),
+         (int)*(ffi_arg *)resp);
+
+}
+
+typedef int (__thiscall *closure_test_type0)(int, int, int, int);
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  ffi_type * cl_arg_types[17];
+  int res;
+  void* sp_pre;
+  void* sp_post;
+  char buf[1024];
+
+  cl_arg_types[0] = &ffi_type_uint;
+  cl_arg_types[1] = &ffi_type_uint;
+  cl_arg_types[2] = &ffi_type_uint;
+  cl_arg_types[3] = &ffi_type_uint;
+  cl_arg_types[4] = NULL;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_THISCALL, 4,
+             &ffi_type_sint, cl_arg_types) == FFI_OK);
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_thiscall,
+                             (void *) 3 /* userdata */, code) == FFI_OK);
+
+  asm volatile (" movl %%esp,%0" : "=g" (sp_pre));
+  res = (*(closure_test_type0)code)(0, 1, 2, 3);
+  asm volatile (" movl %%esp,%0" : "=g" (sp_post));
+  /* { dg-output "0 1 2 3: 9" } */
+
+  printf("res: %d\n",res);
+  /* { dg-output "\nres: 9" } */
+
+  sprintf(buf, "mismatch: pre=%p vs post=%p", sp_pre, sp_post);
+  printf("stack pointer %s\n", (sp_pre == sp_post ? "match" : buf));
+  /* { dg-output "\nstack pointer match" } */
+  exit(0);
+}


  parent reply	other threads:[~2012-01-31  9:47 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-12-10 18:43 [Bug libgcj/51500] New: " jojelino at gmail dot com
2011-12-10 18:59 ` [Bug libgcj/51500] " jojelino at gmail dot com
2011-12-12 10:09 ` rguenth at gcc dot gnu.org
2011-12-12 14:46 ` jojelino at gmail dot com
2011-12-12 14:49 ` jojelino at gmail dot com
2011-12-17 21:56 ` ktietz at gcc dot gnu.org
2011-12-18 22:02 ` jojelino at gmail dot com
2012-01-18 13:37 ` jojelino at gmail dot com
2012-01-30  7:29 ` ktietz at gcc dot gnu.org
2012-01-30 15:11 ` jojelino at gmail dot com
2012-01-30 16:39 ` ubizjak at gmail dot com
2012-01-30 19:20 ` ktietz at gcc dot gnu.org
2012-01-30 19:59 ` ubizjak at gmail dot com
2012-01-30 22:21 ` ktietz at gcc dot gnu.org
2012-01-30 23:05 ` ubizjak at gmail dot com
2012-01-31  9:47 ` ktietz70 at googlemail dot com [this message]
2012-02-01  5:21 ` jojelino at gmail dot com
2012-02-01 10:46 ` ktietz at gcc dot gnu.org
2012-02-05  2:11 ` jojelino at gmail dot com
2012-02-05  2:44 ` jojelino at gmail dot com
2012-02-13 15:20 ` ktietz at gcc dot gnu.org

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bug-51500-8172-sDx1FaPtjc@http.gcc.gnu.org/bugzilla/ \
    --to=gcc-bugzilla@gcc.gnu.org \
    --cc=java-prs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).