summaryrefslogtreecommitdiffstats
path: root/js/src/ctypes/libffi/src/powerpc/sysv.S
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/ctypes/libffi/src/powerpc/sysv.S')
-rw-r--r--js/src/ctypes/libffi/src/powerpc/sysv.S175
1 files changed, 175 insertions, 0 deletions
diff --git a/js/src/ctypes/libffi/src/powerpc/sysv.S b/js/src/ctypes/libffi/src/powerpc/sysv.S
new file mode 100644
index 0000000000..1474ce702b
--- /dev/null
+++ b/js/src/ctypes/libffi/src/powerpc/sysv.S
@@ -0,0 +1,175 @@
+/* -----------------------------------------------------------------------
+ sysv.S - Copyright (c) 1998 Geoffrey Keating
+ Copyright (C) 2007 Free Software Foundation, Inc
+
+ PowerPC Assembly glue.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+#include <powerpc/asm.h>
+
+#ifndef POWERPC64
+FFI_HIDDEN(ffi_call_SYSV)
+ENTRY(ffi_call_SYSV)
+ .cfi_startproc
+ /* Save the old stack pointer as AP. */
+ mr %r10,%r1
+ .cfi_def_cfa_register 10
+
+ /* Allocate the stack space we need. */
+ stwux %r1,%r1,%r8
+ /* Save registers we use. */
+ mflr %r9
+ stw %r28,-16(%r10)
+ stw %r29,-12(%r10)
+ stw %r30, -8(%r10)
+ stw %r31, -4(%r10)
+ stw %r9, 4(%r10)
+ .cfi_offset 65, 4
+ .cfi_offset 31, -4
+ .cfi_offset 30, -8
+ .cfi_offset 29, -12
+ .cfi_offset 28, -16
+
+ /* Save arguments over call... */
+ stw %r7, -20(%r10) /* closure, */
+ mr %r31,%r6 /* flags, */
+ mr %r30,%r5 /* rvalue, */
+ mr %r29,%r4 /* function address, */
+ mr %r28,%r10 /* our AP. */
+ .cfi_def_cfa_register 28
+
+ /* Call ffi_prep_args_SYSV. */
+ mr %r4,%r1
+ bl ffi_prep_args_SYSV@local
+
+ /* Now do the call. */
+ /* Set up cr1 with bits 4-7 of the flags. */
+ mtcrf 0x40,%r31
+ /* Get the address to call into CTR. */
+ mtctr %r29
+ /* Load all those argument registers. */
+ lwz %r3,-24-(8*4)(%r28)
+ lwz %r4,-24-(7*4)(%r28)
+ lwz %r5,-24-(6*4)(%r28)
+ lwz %r6,-24-(5*4)(%r28)
+ bf- 5,1f
+ nop
+ lwz %r7,-24-(4*4)(%r28)
+ lwz %r8,-24-(3*4)(%r28)
+ lwz %r9,-24-(2*4)(%r28)
+ lwz %r10,-24-(1*4)(%r28)
+ nop
+1:
+
+#ifndef __NO_FPRS__
+ /* Load all the FP registers. */
+ bf- 6,2f
+ lfd %f1,-24-(8*4)-(8*8)(%r28)
+ lfd %f2,-24-(8*4)-(7*8)(%r28)
+ lfd %f3,-24-(8*4)-(6*8)(%r28)
+ lfd %f4,-24-(8*4)-(5*8)(%r28)
+ nop
+ lfd %f5,-24-(8*4)-(4*8)(%r28)
+ lfd %f6,-24-(8*4)-(3*8)(%r28)
+ lfd %f7,-24-(8*4)-(2*8)(%r28)
+ lfd %f8,-24-(8*4)-(1*8)(%r28)
+#endif
+2:
+
+ /* Make the call. */
+ lwz %r11, -20(%r28)
+ bctrl
+
+ /* Now, deal with the return value. */
+ 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)
+ mtcrf 0x02,%r31 /* cr6 */
+ bf 27,L(done_return_value)
+ stw %r5,8(%r30)
+ stw %r6,12(%r30)
+ /* Fall through... */
+
+L(done_return_value):
+ /* Restore the registers we used and return. */
+ lwz %r9, 4(%r28)
+ lwz %r31, -4(%r28)
+ mtlr %r9
+ lwz %r30, -8(%r28)
+ lwz %r29,-12(%r28)
+ lwz %r28,-16(%r28)
+ .cfi_remember_state
+ /* At this point we don't have a cfa register. Say all our
+ saved regs have been restored. */
+ .cfi_same_value 65
+ .cfi_same_value 31
+ .cfi_same_value 30
+ .cfi_same_value 29
+ .cfi_same_value 28
+ /* Hopefully this works.. */
+ .cfi_def_cfa_register 1
+ .cfi_offset 1, 0
+ lwz %r1,0(%r1)
+ .cfi_same_value 1
+ blr
+
+#ifndef __NO_FPRS__
+L(fp_return_value):
+ .cfi_restore_state
+ bf 28,L(float_return_value)
+ stfd %f1,0(%r30)
+ mtcrf 0x02,%r31 /* cr6 */
+ bf 27,L(done_return_value)
+ stfd %f2,8(%r30)
+ b L(done_return_value)
+L(float_return_value):
+ stfs %f1,0(%r30)
+ b L(done_return_value)
+#endif
+
+L(small_struct_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)
+ .cfi_endproc
+
+END(ffi_call_SYSV)
+
+#if defined __ELF__ && defined __linux__
+ .section .note.GNU-stack,"",@progbits
+#endif
+#endif