s390: Use pc-relative insns in 31-bit mode
authorRichard Henderson <rth@redhat.com>
Thu, 18 Dec 2014 21:21:07 +0000 (16:21 -0500)
committerRichard Henderson <rth@redhat.com>
Thu, 18 Dec 2014 21:21:07 +0000 (16:21 -0500)
It's silly to stick to esa/390 features when the compiler won't.
Detect when brasl and larl are used by the compiler and then use
them in the assembly.

configure.ac
src/s390/sysv.S

index d5414f9..2941cd7 100644 (file)
@@ -183,6 +183,23 @@ if test x$TARGET = xX86 || test x$TARGET = xX86_WIN32 || test x$TARGET = xX86_64
     fi
 fi
 
+if test x$TARGET = xS390; then
+    AC_CACHE_CHECK([compiler uses zarch features],
+       libffi_cv_as_s390_zarch, [
+       libffi_cv_as_s390_zarch=no
+       echo 'void foo(void) { bar(); bar(); }' > conftest.c
+       if $CC $CFLAGS -S conftest.c > /dev/null 2>&1; then
+           if grep -q brasl conftest.s; then
+               libffi_cv_as_s390_zarch=yes
+           fi
+       fi
+       ])
+    if test "x$libffi_cv_as_s390_zarch" = xyes; then
+       AC_DEFINE(HAVE_AS_S390_ZARCH, 1,
+                 [Define if the compiler uses zarch features.])
+    fi
+fi
+
 # On PaX enable kernels that have MPROTECT enable we can't use PROT_EXEC.
 AC_ARG_ENABLE(pax_emutramp,
   [  --enable-pax_emutramp       enable pax emulated trampolines, for we can't use PROT_EXEC],
index df9083e..1869269 100644 (file)
@@ -55,13 +55,21 @@ ffi_call_SYSV:
        .cfi_rel_offset r14, 56
        .cfi_def_cfa_register r13
        l       %r15,60(%r2)                    # Set up outgoing stack
+#ifdef HAVE_AS_S390_ZARCH
+       larl    %r14,.Ltable
+#else
        basr    %r14,0                          # Set up base register
 .Lbase:
+#endif
        sla     %r3,3                           # ret_type *= 8
        lr      %r12,%r4                        # Save ret_addr
        lr      %r1,%r5                         # Save fun
        lr      %r0,%r6                         # Install static chain
+#ifdef HAVE_AS_S390_ZARCH
+       la      %r14,0(%r14,%r3)                # Set return address
+#else
        la      %r14,.Ltable-.Lbase(%r14,%r3)   # Set return address
+#endif
        lm      %r2,%r6,8(%r13)                 # Load arguments
        ld      %f0,64(%r13)
        ld      %f2,72(%r13)
@@ -141,10 +149,12 @@ ffi_closure_SYSV:
        .cfi_rel_offset r13, 52
        .cfi_rel_offset r14, 56
        .cfi_rel_offset r15, 60
+#ifndef HAVE_AS_S390_ZARCH
        basr    %r13,0                          # Set up base register
 .Lcbase:
-       ahi     %r15,-96-8                      # Set up stack frame
        l       %r1,.Lchelper-.Lcbase(%r13)     # Get helper function
+#endif
+       ahi     %r15,-96-8                      # Set up stack frame
        st      %r12,0(%r15)                    # Set up back chain
 
        std     %f0,64(%r12)                    # Save fp arguments
@@ -154,7 +164,11 @@ ffi_closure_SYSV:
        st      %r5,96(%r15)
        la      %r6,64(%r12)                    # FPRs
        la      %r5,8(%r12)                     # GPRs
+#ifdef HAVE_AS_S390_ZARCH
+       brasl   %r14,ffi_closure_helper_SYSV
+#else
        bas     %r14,0(%r1,%r13)                # Call helper
+#endif
 
        lr      %r15,%r12
        .cfi_def_cfa_register r15
@@ -165,10 +179,11 @@ ffi_closure_SYSV:
        br      %r14
        .cfi_endproc
 
+#ifndef HAVE_AS_S390_ZARCH
        .align 4
 .Lchelper:
        .long   ffi_closure_helper_SYSV-.Lcbase
-
+#endif
 
        .size    ffi_closure_SYSV,.-ffi_closure_SYSV