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