summaryrefslogtreecommitdiff
path: root/ext/ffi_c/libffi/src/powerpc/sysv.S
diff options
context:
space:
mode:
Diffstat (limited to 'ext/ffi_c/libffi/src/powerpc/sysv.S')
-rw-r--r--ext/ffi_c/libffi/src/powerpc/sysv.S31
1 files changed, 16 insertions, 15 deletions
diff --git a/ext/ffi_c/libffi/src/powerpc/sysv.S b/ext/ffi_c/libffi/src/powerpc/sysv.S
index 96ea22b..fed2380 100644
--- a/ext/ffi_c/libffi/src/powerpc/sysv.S
+++ b/ext/ffi_c/libffi/src/powerpc/sysv.S
@@ -30,7 +30,7 @@
#include <ffi.h>
#include <powerpc/asm.h>
-#ifndef __powerpc64__
+#ifndef POWERPC64
.globl ffi_prep_args_SYSV
ENTRY(ffi_call_SYSV)
.LFB1:
@@ -83,6 +83,7 @@ ENTRY(ffi_call_SYSV)
nop
1:
+#ifndef __NO_FPRS__
/* Load all the FP registers. */
bf- 6,2f
lfd %f1,-16-(8*4)-(8*8)(%r28)
@@ -94,6 +95,7 @@ ENTRY(ffi_call_SYSV)
lfd %f6,-16-(8*4)-(3*8)(%r28)
lfd %f7,-16-(8*4)-(2*8)(%r28)
lfd %f8,-16-(8*4)-(1*8)(%r28)
+#endif
2:
/* Make the call. */
@@ -103,7 +105,9 @@ ENTRY(ffi_call_SYSV)
mtcrf 0x01,%r31 /* cr7 */
bt- 31,L(small_struct_return_value)
bt- 30,L(done_return_value)
+#ifndef __NO_FPRS__
bt- 29,L(fp_return_value)
+#endif
stw %r3,0(%r30)
bf+ 28,L(done_return_value)
stw %r4,4(%r30)
@@ -124,6 +128,7 @@ L(done_return_value):
lwz %r1,0(%r1)
blr
+#ifndef __NO_FPRS__
L(fp_return_value):
bf 28,L(float_return_value)
stfd %f1,0(%r30)
@@ -134,21 +139,17 @@ L(fp_return_value):
L(float_return_value):
stfs %f1,0(%r30)
b L(done_return_value)
+#endif
L(small_struct_return_value):
- extrwi %r6,%r31,2,19 /* number of bytes padding = shift/8 */
- mtcrf 0x02,%r31 /* copy flags to cr[24:27] (cr6) */
- extrwi %r5,%r31,5,19 /* r5 <- number of bits of padding */
- subfic %r6,%r6,4 /* r6 <- number of useful bytes in r3 */
- bf- 25,L(done_return_value) /* struct in r3 ? if not, done. */
-/* smst_one_register: */
- slw %r3,%r3,%r5 /* Left-justify value in r3 */
- mtxer %r6 /* move byte count to XER ... */
- stswx %r3,0,%r30 /* ... and store that many bytes */
- bf+ 26,L(done_return_value) /* struct in r3:r4 ? */
- add %r6,%r6,%r30 /* adjust pointer */
- stswi %r4,%r6,4 /* store last four bytes */
- b L(done_return_value)
+ /*
+ * The C code always allocates a properly-aligned 8-byte bounce
+ * buffer to make this assembly code very simple. Just write out
+ * r3 and r4 to the buffer to allow the C code to handle the rest.
+ */
+ stw %r3, 0(%r30)
+ stw %r4, 4(%r30)
+ b L(done_return_value)
.LFE1:
END(ffi_call_SYSV)
@@ -212,8 +213,8 @@ END(ffi_call_SYSV)
.uleb128 0x1c
.align 2
.LEFDE1:
-#endif
#if defined __ELF__ && defined __linux__
.section .note.GNU-stack,"",@progbits
#endif
+#endif