summaryrefslogtreecommitdiffstats
path: root/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_mips.s
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_mips.s166
1 files changed, 166 insertions, 0 deletions
diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_mips.s b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_mips.s
new file mode 100644
index 00000000..f011aaf5
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_mips.s
@@ -0,0 +1,166 @@
+/* -*- Mode: asm; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corp, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2001
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Brendan Eich <brendan@mozilla.org>
+ * Stuart Parmenter <pavlov@netscape.com>
+ */
+
+/* This code is for MIPS using the O32 ABI. */
+
+#include <sys/regdef.h>
+#include <sys/asm.h>
+
+.text
+.globl invoke_count_words
+.globl invoke_copy_to_stack
+
+# We need a variable number of words allocated from the stack for copies of
+# the params, and this space must come between the high frame (where ra, gp,
+# and s0 are saved) and the low frame (where a0-a3 are saved by the callee
+# functions we invoke).
+
+LOCALSZ=4 # s0, s1, ra, gp
+NARGSAVE=4 # a0, a1, a2, a3
+HIFRAMESZ=(LOCALSZ*SZREG)
+LOFRAMESZ=(NARGSAVE*SZREG)
+FRAMESZ=(HIFRAMESZ+LOFRAMESZ+ALSZ)&ALMASK
+
+# XXX these 2*SZREG, etc. are very magic -- we *know* that ALSZ&ALMASK cause
+# FRAMESZ to be 0 mod 8, in this case to be 16 and not 12.
+RAOFF=FRAMESZ - (2*SZREG)
+GPOFF=FRAMESZ - (3*SZREG)
+S0OFF=FRAMESZ - (4*SZREG)
+S1OFF=FRAMESZ - (5*SZREG)
+
+# These are not magic -- they are just our argsave slots in the caller frame.
+A0OFF=FRAMESZ
+A1OFF=FRAMESZ + (1*SZREG)
+A2OFF=FRAMESZ + (2*SZREG)
+A3OFF=FRAMESZ + (3*SZREG)
+
+ #
+ # _XPTC_InvokeByIndex(that, methodIndex, paramCount, params)
+ # a0 a1 a2 a3
+
+NESTED(_XPTC_InvokeByIndex, FRAMESZ, ra)
+
+ .set noreorder
+ .cpload t9
+ .set reorder
+
+ subu sp, FRAMESZ
+
+ # specify the save register mask -- XXX do we want the a0-a3 here, given
+ # our "split" frame where the args are saved below a dynamicly allocated
+ # region under the high frame?
+ #
+ # 10010000000000010000000011110000
+ .mask 0x900100F0, -((NARGSAVE+LOCALSZ)*SZREG)
+
+ # thou shalt not use .cprestore if yer frame has variable size...
+ # .cprestore GPOFF
+
+ REG_S ra, RAOFF(sp)
+
+ # this happens automatically with .cprestore, but we cannot use that op...
+ REG_S gp, GPOFF(sp)
+ REG_S s0, S0OFF(sp)
+ REG_S s1, S1OFF(sp)
+
+ REG_S a0, A0OFF(sp)
+ REG_S a1, A1OFF(sp)
+ REG_S a2, A2OFF(sp)
+ REG_S a3, A3OFF(sp)
+
+ # invoke_count_words(paramCount, params)
+ move a0, a2
+ move a1, a3
+
+ jal invoke_count_words
+ lw gp, GPOFF(sp)
+
+ # save the old sp so we can pop the param area and any "low frame"
+ # needed as an argsave area below the param block for callees that
+ # we invoke.
+ move s0, sp
+
+ REG_L a1, A2OFF(sp) # a1 = paramCount
+ REG_L a2, A3OFF(sp) # a2 = params
+
+ # we define a word as 4 bytes, period end of story!
+ sll v0, 2 # 4 bytes * result of invoke_copy_words
+ subu v0, LOFRAMESZ # but we take back the argsave area built into
+ # our stack frame -- SWEET!
+ subu sp, sp, v0 # make room
+ move a0, sp # a0 = param stack address
+ move s1, a0 # save it for later -- it should be safe here
+
+ # the old sp is still saved in s0, but we now need another argsave
+ # area ("low frame") for the invoke_copy_to_stack call.
+ subu sp, sp, LOFRAMESZ
+
+ # copy the param into the stack areas
+ # invoke_copy_to_stack(PRUint32* d, PRUint32 paramCount,
+ # nsXPTCVariant* s)
+ jal invoke_copy_to_stack
+ lw gp, GPOFF(s0)
+
+ move sp, s0 # get orig sp back, popping params and argsave
+
+ REG_L a0, A0OFF(sp) # a0 = set "that" to be "this"
+ REG_L a1, A1OFF(sp) # a1 = methodIndex
+
+ # t1 = methodIndex * 4
+ # (use shift instead of mult)
+ sll t1, a1, 2
+
+ # calculate the function we need to jump to,
+ # which must then be saved in t9
+ lw t9, 0(a0)
+ addu t9, t9, t1
+ lw t9, 8(t9)
+
+ # a1..a3 and f13..f14 should now be set to what
+ # invoke_copy_to_stack told us. skip a0 and f12
+ # because that is the "this" pointer
+
+ REG_L a1, 1*SZREG(s1)
+ REG_L a2, 2*SZREG(s1)
+ REG_L a3, 3*SZREG(s1)
+
+ l.d $f13, 8(s1)
+ l.d $f14, 16(s1)
+
+ # Create the stack pointer for the function, which must have 4 words
+ # of space for callee-saved args. invoke_count_words allocated space
+ # for a0 starting at s1, so we just move s1 into sp.
+ move sp, s1
+
+ jalr ra, t9
+ lw gp, GPOFF(s0)
+
+ move sp, s0
+
+ REG_L ra, RAOFF(sp)
+ REG_L s0, S0OFF(sp)
+ addu sp, FRAMESZ
+ j ra
+.end _XPTC_InvokeByIndex