diff options
Diffstat (limited to 'xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_mips.S')
-rw-r--r-- | xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_mips.S | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_mips.S b/xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_mips.S new file mode 100644 index 0000000000..32ff3b3565 --- /dev/null +++ b/xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_mips.S @@ -0,0 +1,134 @@ +/* -*- Mode: asm; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * Version: MPL 1.1 + * + * 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/. */ + +/* This code is for MIPS using the O32 ABI. */ + +#ifdef ANDROID +#include <asm/regdef.h> +#include <asm/asm.h> +#include <machine/asm.h> +#else +#include <sys/regdef.h> +#include <sys/asm.h> +#endif + +# NARGSAVE is the argument space in the callers frame, including extra +# 'shadowed' space for the argument registers. The minimum of 4 +# argument slots is sometimes predefined in the header files. +#ifndef NARGSAVE +#define NARGSAVE 4 +#endif + +#define LOCALSZ 3 /* gp, fp, ra */ +#define FRAMESZ ((((NARGSAVE+LOCALSZ)*SZREG)+ALSZ)&ALMASK) + +#define RAOFF (FRAMESZ - (1*SZREG)) +#define FPOFF (FRAMESZ - (2*SZREG)) +#define GPOFF (FRAMESZ - (3*SZREG)) + +#define A0OFF (FRAMESZ + (0*SZREG)) +#define A1OFF (FRAMESZ + (1*SZREG)) +#define A2OFF (FRAMESZ + (2*SZREG)) +#define A3OFF (FRAMESZ + (3*SZREG)) + + .text + +# +# _NS_InvokeByIndex(that, methodIndex, paramCount, params) +# a0 a1 a2 a3 + + .globl _NS_InvokeByIndex + .align 2 + .type _NS_InvokeByIndex,@function + .ent _NS_InvokeByIndex,0 + .frame fp, FRAMESZ, ra +_NS_InvokeByIndex: + SETUP_GP + subu sp, FRAMESZ + + # specify the save register mask for gp, fp, ra, a3 - a0 + .mask 0xD00000F0, RAOFF-FRAMESZ + + sw ra, RAOFF(sp) + sw fp, FPOFF(sp) + + # we can't use .cprestore in a variable stack frame + sw gp, GPOFF(sp) + + sw a0, A0OFF(sp) + sw a1, A1OFF(sp) + sw a2, A2OFF(sp) + sw a3, A3OFF(sp) + + # save bottom of fixed frame + move fp, sp + + # extern "C" uint32 + # invoke_count_words(uint32_t paramCount, nsXPTCVariant* s); + la t9, invoke_count_words + move a0, a2 + move a1, a3 + jalr t9 + lw gp, GPOFF(fp) + + # allocate variable stack, with a size of: + # wordsize (of 4 bytes) * result (already aligned to dword) + # but a minimum of 16 byte + sll v0, 2 + slt t0, v0, 16 + beqz t0, 1f + li v0, 16 +1: subu sp, v0 + + # let a0 point to the bottom of the variable stack, allocate + # another fixed stack for: + # extern "C" void + # invoke_copy_to_stack(uint32_t* d, uint32_t paramCount, + # nsXPTCVariant* s); + la t9, invoke_copy_to_stack + move a0, sp + lw a1, A2OFF(fp) + lw a2, A3OFF(fp) + subu sp, 16 + jalr t9 + lw gp, GPOFF(fp) + + # back to the variable stack frame + addu sp, 16 + + # calculate the function we need to jump to, which must then be + # stored in t9 + lw a0, A0OFF(fp) # a0 = set "that" to be "this" + lw t0, A1OFF(fp) # a1 = methodIndex + lw t9, 0(a0) + # t0 = methodIndex << PTRLOG + sll t0, t0, PTRLOG + addu t9, t0 + lw t9, (t9) + + # Set a1-a3 to what invoke_copy_to_stack told us. a0 is already + # the "this" pointer. We don't have to care about floating + # point arguments, the non-FP "this" pointer as first argument + # means they'll never be used. + lw a1, 1*SZREG(sp) + lw a2, 2*SZREG(sp) + lw a3, 3*SZREG(sp) + + jalr t9 + # Micro-optimization: There's no gp usage below this point, so + # we don't reload. + # lw gp, GPOFF(fp) + + # leave variable stack frame + move sp, fp + + lw ra, RAOFF(sp) + lw fp, FPOFF(sp) + + addiu sp, FRAMESZ + j ra +END(_NS_InvokeByIndex) |