summaryrefslogtreecommitdiffstats
path: root/xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_mips64.S
diff options
context:
space:
mode:
Diffstat (limited to 'xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_mips64.S')
-rw-r--r--xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_mips64.S121
1 files changed, 121 insertions, 0 deletions
diff --git a/xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_mips64.S b/xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_mips64.S
new file mode 100644
index 0000000000..d2c5595ab4
--- /dev/null
+++ b/xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_mips64.S
@@ -0,0 +1,121 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+#include <sys/regdef.h>
+#include <sys/asm.h>
+
+.text
+.globl invoke_count_words
+.globl invoke_copy_to_stack
+
+LOCALSZ=7 # a0, a1, a2, a3, s0, ra, gp
+FRAMESZ=(((NARGSAVE+LOCALSZ)*SZREG)+ALSZ)&ALMASK
+
+RAOFF=FRAMESZ-(1*SZREG)
+A0OFF=FRAMESZ-(2*SZREG)
+A1OFF=FRAMESZ-(3*SZREG)
+A2OFF=FRAMESZ-(4*SZREG)
+A3OFF=FRAMESZ-(5*SZREG)
+S0OFF=FRAMESZ-(6*SZREG)
+GPOFF=FRAMESZ-(7*SZREG)
+
+#
+# _NS_InvokeByIndex(that, methodIndex, paramCount, params)
+# a0 a1 a2 a3
+
+NESTED(_NS_InvokeByIndex, FRAMESZ, ra)
+ PTR_SUBU sp, FRAMESZ
+ SETUP_GP64(GPOFF, _NS_InvokeByIndex)
+
+ REG_S ra, RAOFF(sp)
+ REG_S a0, A0OFF(sp)
+ REG_S a1, A1OFF(sp)
+ REG_S a2, A2OFF(sp)
+ REG_S a3, A3OFF(sp)
+ REG_S s0, S0OFF(sp)
+
+ # invoke_count_words(paramCount, params)
+ move a0, a2
+ move a1, a3
+ jal invoke_count_words
+
+ # invoke_copy_to_stack(uint32_t* d, uint32_t paramCount,
+ # nsXPTCVariant* s, uint32_t *reg)
+
+ REG_L a1, A2OFF(sp) # a1 - paramCount
+ REG_L a2, A3OFF(sp) # a2 - params
+
+ # save sp before we copy the params to the stack
+ move t0, sp
+
+ # assume full size of 16 bytes per param to be safe
+ sll v0, 4 # 16 bytes * num params
+ PTR_SUBU sp, sp, v0 # make room
+ move a0, sp # a0 - param stack address
+
+ # create temporary stack space to write int and fp regs
+ PTR_SUBU sp, 64 # 64 = 8 regs of 8 bytes
+ move a3, sp
+
+ # save the old sp and save the arg stack
+ PTR_SUBU sp, sp, 16
+ REG_S t0, 0(sp)
+ REG_S a0, 8(sp)
+
+ # copy the param into the stack areas
+ jal invoke_copy_to_stack
+
+ REG_L t3, 8(sp) # get previous a0
+ REG_L s0, 0(sp) # get orig sp back and save away our stack pointer
+
+ REG_L a0, A0OFF(s0) # a0 - that
+ REG_L a1, A1OFF(s0) # a1 - methodIndex
+
+ # t1 = methodIndex * pow(2, PTRLOG)
+ # (use shift instead of mult)
+ sll t1, a1, PTRLOG
+
+ # calculate the function we need to jump to,
+ # which must then be saved in t9
+ PTR_L t9, 0(a0)
+ PTR_ADDU t9, t9, t1
+ PTR_L t9, (t9)
+
+ # get register save area from invoke_copy_to_stack
+ PTR_SUBU t1, t3, 64
+
+ # a1..a7 and f13..f19 should now be set to what
+ # invoke_copy_to_stack told us. skip a0 and f12
+ # because that's the "this" pointer
+
+ REG_L a1, 0(t1)
+ REG_L a2, 8(t1)
+ REG_L a3, 16(t1)
+ REG_L a4, 24(t1)
+ REG_L a5, 32(t1)
+ REG_L a6, 40(t1)
+ REG_L a7, 48(t1)
+
+ l.d $f13, 0(t1)
+ l.d $f14, 8(t1)
+ l.d $f15, 16(t1)
+ l.d $f16, 24(t1)
+ l.d $f17, 32(t1)
+ l.d $f18, 40(t1)
+ l.d $f19, 48(t1)
+
+ # create the stack pointer for the function
+ move sp, t3
+
+ jalr t9
+
+ ## restore stack pointer.
+ move sp, s0
+
+ RESTORE_GP64
+ REG_L ra, RAOFF(sp)
+ REG_L s0, S0OFF(sp)
+ PTR_ADDU sp, FRAMESZ
+ j ra
+.end _NS_InvokeByIndex