Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r80340:01e9463e526f
Date: 2015-10-19 20:47 +0200
http://bitbucket.org/pypy/pypy/changeset/01e9463e526f/

Log:    Maybe found a solution

diff --git a/rpython/translator/c/src/stacklet/switch_arm_gcc.h 
b/rpython/translator/c/src/stacklet/switch_arm_gcc.h
--- a/rpython/translator/c/src/stacklet/switch_arm_gcc.h
+++ b/rpython/translator/c/src/stacklet/switch_arm_gcc.h
@@ -7,6 +7,10 @@
 
 static void *slp_switch(void *(*save_state)(void*, void*),
                         void *(*restore_state)(void*, void*),
+                        void *extra) __attribute__((noinline));
+
+static void *slp_switch(void *(*save_state)(void*, void*),
+                        void *(*restore_state)(void*, void*),
                         void *extra)
 {
   void *result;
@@ -23,6 +27,20 @@
     "and r1, r0, #-16\n"
     "mov sp, r1\n"
     "push {r0, r2, r3, r7, r8, r9, r10, r11}\n"   /* total 8, still aligned */
+#ifndef __SOFTFP__
+    /* We also push d8-d15 to preserve them explicitly.  This assumes
+     * that this code is in a function that doesn't use floating-point
+     * at all, and so don't touch the "d" registers (that's why we mark
+     * it as non-inlinable).  So here by pushing/poping d8-d15 we are
+     * saving precisely the callee-saved registers in all cases.  We
+     * could also try to list all "d" registers as clobbered, but it
+     * doesn't work: there is no way I could find to know if we have 16
+     * or 32 "d" registers (depends on the exact -mcpu=... and we don't
+     * know it from the C code).  If we have 32, then gcc would "save"
+     * d8-d15 by copying them into d16-d23 for example, and it doesn't
+     * work. */
+    "vpush {d8, d9, d10, d11, d12, d13, d14, d15}\n"  /* 16 words, still 
aligned */
+#endif
 
     /* save values in callee saved registers for later */
     "mov r4, %[restore_state]\n"  /* can't be r0 or r1: marked clobbered */
@@ -47,6 +65,9 @@
     /* The stack's content is now restored. */
     "zero:\n"
 
+#ifndef __SOFTFP__
+    "vpop {d8, d9, d10, d11, d12, d13, d14, d15}\n"
+#endif
     "pop {r1, r2, r3, r7, r8, r9, r10, r11}\n"
     "mov sp, r1\n"
     "mov %[result], r0\n"
@@ -58,28 +79,6 @@
       [extra]"r"(extra)
     : "r0", "r1", "r4", "r5", "r6", "r12", "lr",
       "memory", "cc"
-#ifndef __SOFTFP__
-      , "d0", "d1", "d2",  "d3",  "d4",  "d5",  "d6",  "d7"
-      , "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15"
-/* messsssssssssssss quite unsure it is the correct way */
-/* Actually it seems there is no way.  These macros are defined by ARM's
- * own compiler but not by GCC.  On GCC, by looking at its sources it
- * seems that we'd like to know the internal TARGET_VFPD32 flag, but
- * there is no way to access it because it's not exported as a macro.
- * We loose.  If you compile for some architecture with 32 "d"
- * registers, gcc will likely move the registers to save (d8-d15)
- * into some of d16-d31, and they will then be clobbered.
- * I don't see any solution. :-((
- */
-# if defined(__TARGET_FPU_SOFTVFP_VFPV3) || \
-     defined(__TARGET_FPU_SOFTVFP_VFPV3_FP16) || \
-     defined(__TARGET_FPU_VFPV3) || \
-     defined(__TARGET_FPU_VFPV3_FP16) || \
-     defined(__TARGET_FPU_VFPV4)
-      , "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23"
-      , "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31"
-# endif
-#endif
   );
   return result;
 }
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to