michael@0: /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 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: #include michael@0: #include michael@0: michael@0: .text michael@0: .globl invoke_count_words michael@0: .globl invoke_copy_to_stack michael@0: michael@0: LOCALSZ=7 # a0, a1, a2, a3, s0, ra, gp michael@0: FRAMESZ=(((NARGSAVE+LOCALSZ)*SZREG)+ALSZ)&ALMASK michael@0: michael@0: RAOFF=FRAMESZ-(1*SZREG) michael@0: A0OFF=FRAMESZ-(2*SZREG) michael@0: A1OFF=FRAMESZ-(3*SZREG) michael@0: A2OFF=FRAMESZ-(4*SZREG) michael@0: A3OFF=FRAMESZ-(5*SZREG) michael@0: S0OFF=FRAMESZ-(6*SZREG) michael@0: GPOFF=FRAMESZ-(7*SZREG) michael@0: michael@0: # michael@0: # _NS_InvokeByIndex(that, methodIndex, paramCount, params) michael@0: # a0 a1 a2 a3 michael@0: michael@0: NESTED(_NS_InvokeByIndex, FRAMESZ, ra) michael@0: PTR_SUBU sp, FRAMESZ michael@0: SETUP_GP64(GPOFF, _NS_InvokeByIndex) michael@0: michael@0: REG_S ra, RAOFF(sp) michael@0: REG_S a0, A0OFF(sp) michael@0: REG_S a1, A1OFF(sp) michael@0: REG_S a2, A2OFF(sp) michael@0: REG_S a3, A3OFF(sp) michael@0: REG_S s0, S0OFF(sp) michael@0: michael@0: # invoke_count_words(paramCount, params) michael@0: move a0, a2 michael@0: move a1, a3 michael@0: jal invoke_count_words michael@0: michael@0: # invoke_copy_to_stack(uint32_t* d, uint32_t paramCount, michael@0: # nsXPTCVariant* s, uint32_t *reg) michael@0: michael@0: REG_L a1, A2OFF(sp) # a1 - paramCount michael@0: REG_L a2, A3OFF(sp) # a2 - params michael@0: michael@0: # save sp before we copy the params to the stack michael@0: move t0, sp michael@0: michael@0: # assume full size of 16 bytes per param to be safe michael@0: sll v0, 4 # 16 bytes * num params michael@0: subu sp, sp, v0 # make room michael@0: move a0, sp # a0 - param stack address michael@0: michael@0: # create temporary stack space to write int and fp regs michael@0: subu sp, 64 # 64 = 8 regs of 8 bytes michael@0: move a3, sp michael@0: michael@0: # save the old sp and save the arg stack michael@0: subu sp, sp, 16 michael@0: REG_S t0, 0(sp) michael@0: REG_S a0, 8(sp) michael@0: michael@0: # copy the param into the stack areas michael@0: jal invoke_copy_to_stack michael@0: michael@0: REG_L t3, 8(sp) # get previous a0 michael@0: REG_L sp, 0(sp) # get orig sp back michael@0: michael@0: REG_L a0, A0OFF(sp) # a0 - that michael@0: REG_L a1, A1OFF(sp) # a1 - methodIndex michael@0: michael@0: # t1 = methodIndex * pow(2, PTRLOG) michael@0: # (use shift instead of mult) michael@0: sll t1, a1, PTRLOG michael@0: michael@0: # calculate the function we need to jump to, michael@0: # which must then be saved in t9 michael@0: lw t9, 0(a0) michael@0: addu t9, t9, t1 michael@0: lw t9, (t9) michael@0: michael@0: # get register save area from invoke_copy_to_stack michael@0: subu t1, t3, 64 michael@0: michael@0: # a1..a7 and f13..f19 should now be set to what michael@0: # invoke_copy_to_stack told us. skip a0 and f12 michael@0: # because that's the "this" pointer michael@0: michael@0: REG_L a1, 0(t1) michael@0: REG_L a2, 8(t1) michael@0: REG_L a3, 16(t1) michael@0: REG_L a4, 24(t1) michael@0: REG_L a5, 32(t1) michael@0: REG_L a6, 40(t1) michael@0: REG_L a7, 48(t1) michael@0: michael@0: l.d $f13, 0(t1) michael@0: l.d $f14, 8(t1) michael@0: l.d $f15, 16(t1) michael@0: l.d $f16, 24(t1) michael@0: l.d $f17, 32(t1) michael@0: l.d $f18, 40(t1) michael@0: l.d $f19, 48(t1) michael@0: michael@0: # save away our stack pointer and create michael@0: # the stack pointer for the function michael@0: move s0, sp michael@0: move sp, t3 michael@0: michael@0: jalr t9 michael@0: michael@0: move sp, s0 michael@0: michael@0: RESTORE_GP64 michael@0: REG_L ra, RAOFF(sp) michael@0: REG_L s0, S0OFF(sp) michael@0: PTR_ADDU sp, FRAMESZ michael@0: j ra michael@0: .end _NS_InvokeByIndex