michael@0: /* -*- Mode: asm; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- michael@0: * Version: MPL 1.1 michael@0: * michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /* This code is for MIPS using the O32 ABI. */ michael@0: michael@0: #ifdef ANDROID michael@0: #include michael@0: #include michael@0: #include michael@0: #else michael@0: #include michael@0: #include michael@0: #endif michael@0: michael@0: # NARGSAVE is the argument space in the callers frame, including extra michael@0: # 'shadowed' space for the argument registers. The minimum of 4 michael@0: # argument slots is sometimes predefined in the header files. michael@0: #ifndef NARGSAVE michael@0: #define NARGSAVE 4 michael@0: #endif michael@0: michael@0: #define LOCALSZ 3 /* gp, fp, ra */ michael@0: #define FRAMESZ ((((NARGSAVE+LOCALSZ)*SZREG)+ALSZ)&ALMASK) michael@0: michael@0: #define RAOFF (FRAMESZ - (1*SZREG)) michael@0: #define FPOFF (FRAMESZ - (2*SZREG)) michael@0: #define GPOFF (FRAMESZ - (3*SZREG)) michael@0: michael@0: #define A0OFF (FRAMESZ + (0*SZREG)) michael@0: #define A1OFF (FRAMESZ + (1*SZREG)) michael@0: #define A2OFF (FRAMESZ + (2*SZREG)) michael@0: #define A3OFF (FRAMESZ + (3*SZREG)) michael@0: michael@0: .text michael@0: michael@0: # michael@0: # _NS_InvokeByIndex(that, methodIndex, paramCount, params) michael@0: # a0 a1 a2 a3 michael@0: michael@0: .globl _NS_InvokeByIndex michael@0: .align 2 michael@0: .type _NS_InvokeByIndex,@function michael@0: .ent _NS_InvokeByIndex,0 michael@0: .frame fp, FRAMESZ, ra michael@0: _NS_InvokeByIndex: michael@0: SETUP_GP michael@0: subu sp, FRAMESZ michael@0: michael@0: # specify the save register mask for gp, fp, ra, a3 - a0 michael@0: .mask 0xD00000F0, RAOFF-FRAMESZ michael@0: michael@0: sw ra, RAOFF(sp) michael@0: sw fp, FPOFF(sp) michael@0: michael@0: # we can't use .cprestore in a variable stack frame michael@0: sw gp, GPOFF(sp) michael@0: michael@0: sw a0, A0OFF(sp) michael@0: sw a1, A1OFF(sp) michael@0: sw a2, A2OFF(sp) michael@0: sw a3, A3OFF(sp) michael@0: michael@0: # save bottom of fixed frame michael@0: move fp, sp michael@0: michael@0: # extern "C" uint32 michael@0: # invoke_count_words(uint32_t paramCount, nsXPTCVariant* s); michael@0: la t9, invoke_count_words michael@0: move a0, a2 michael@0: move a1, a3 michael@0: jalr t9 michael@0: lw gp, GPOFF(fp) michael@0: michael@0: # allocate variable stack, with a size of: michael@0: # wordsize (of 4 bytes) * result (already aligned to dword) michael@0: # but a minimum of 16 byte michael@0: sll v0, 2 michael@0: slt t0, v0, 16 michael@0: beqz t0, 1f michael@0: li v0, 16 michael@0: 1: subu sp, v0 michael@0: michael@0: # let a0 point to the bottom of the variable stack, allocate michael@0: # another fixed stack for: michael@0: # extern "C" void michael@0: # invoke_copy_to_stack(uint32_t* d, uint32_t paramCount, michael@0: # nsXPTCVariant* s); michael@0: la t9, invoke_copy_to_stack michael@0: move a0, sp michael@0: lw a1, A2OFF(fp) michael@0: lw a2, A3OFF(fp) michael@0: subu sp, 16 michael@0: jalr t9 michael@0: lw gp, GPOFF(fp) michael@0: michael@0: # back to the variable stack frame michael@0: addu sp, 16 michael@0: michael@0: # calculate the function we need to jump to, which must then be michael@0: # stored in t9 michael@0: lw a0, A0OFF(fp) # a0 = set "that" to be "this" michael@0: lw t0, A1OFF(fp) # a1 = methodIndex michael@0: lw t9, 0(a0) michael@0: # t0 = methodIndex << PTRLOG michael@0: sll t0, t0, PTRLOG michael@0: addu t9, t0 michael@0: lw t9, (t9) michael@0: michael@0: # Set a1-a3 to what invoke_copy_to_stack told us. a0 is already michael@0: # the "this" pointer. We don't have to care about floating michael@0: # point arguments, the non-FP "this" pointer as first argument michael@0: # means they'll never be used. michael@0: lw a1, 1*SZREG(sp) michael@0: lw a2, 2*SZREG(sp) michael@0: lw a3, 3*SZREG(sp) michael@0: michael@0: jalr t9 michael@0: # Micro-optimization: There's no gp usage below this point, so michael@0: # we don't reload. michael@0: # lw gp, GPOFF(fp) michael@0: michael@0: # leave variable stack frame michael@0: move sp, fp michael@0: michael@0: lw ra, RAOFF(sp) michael@0: lw fp, FPOFF(sp) michael@0: michael@0: addiu sp, FRAMESZ michael@0: j ra michael@0: END(_NS_InvokeByIndex)