michael@0: /* -*- Mode: asm; tab-width: 4; 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: 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 2 /* gp, ra */ michael@0: #define FRAMESZ ((((NARGSAVE+LOCALSZ)*SZREG)+ALSZ)&ALMASK) michael@0: michael@0: #define RAOFF (FRAMESZ - (1*SZREG)) michael@0: #define GPOFF (FRAMESZ - (2*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: #define STUB_ENTRY(x) \ michael@0: .if x < 10; \ michael@0: .globl _ZN14nsXPTCStubBase5Stub ##x ##Ev; \ michael@0: .type _ZN14nsXPTCStubBase5Stub ##x ##Ev,@function; \ michael@0: .aent _ZN14nsXPTCStubBase5Stub ##x ##Ev,0; \ michael@0: _ZN14nsXPTCStubBase5Stub ##x ##Ev:; \ michael@0: SETUP_GP; \ michael@0: li t0,x; \ michael@0: b sharedstub; \ michael@0: .elseif x < 100; \ michael@0: .globl _ZN14nsXPTCStubBase6Stub ##x ##Ev; \ michael@0: .type _ZN14nsXPTCStubBase6Stub ##x ##Ev,@function; \ michael@0: .aent _ZN14nsXPTCStubBase6Stub ##x ##Ev,0; \ michael@0: _ZN14nsXPTCStubBase6Stub ##x ##Ev:; \ michael@0: SETUP_GP; \ michael@0: li t0,x; \ michael@0: b sharedstub; \ michael@0: .elseif x < 1000; \ michael@0: .globl _ZN14nsXPTCStubBase7Stub ##x ##Ev; \ michael@0: .type _ZN14nsXPTCStubBase7Stub ##x ##Ev,@function; \ michael@0: .aent _ZN14nsXPTCStubBase7Stub ##x ##Ev,0; \ michael@0: _ZN14nsXPTCStubBase7Stub ##x ##Ev:; \ michael@0: SETUP_GP; \ michael@0: li t0,x; \ michael@0: b sharedstub; \ michael@0: .else; \ michael@0: .err; \ michael@0: .endif michael@0: michael@0: # SENTINEL_ENTRY is handled in the cpp file. michael@0: #define SENTINEL_ENTRY(x) michael@0: michael@0: # michael@0: # open a dummy frame for the function entries michael@0: # michael@0: .align 2 michael@0: .type dummy,@function michael@0: .ent dummy, 0 michael@0: .frame sp, FRAMESZ, ra michael@0: dummy: michael@0: SETUP_GP michael@0: michael@0: #include "xptcstubsdef.inc" michael@0: michael@0: sharedstub: michael@0: subu sp, FRAMESZ michael@0: michael@0: # specify the save register mask for gp, ra, a0-a3 michael@0: .mask 0x900000F0, RAOFF-FRAMESZ michael@0: michael@0: sw ra, RAOFF(sp) michael@0: SAVE_GP(GPOFF) michael@0: michael@0: # Micro-optimization: a0 is already loaded, and its slot gets michael@0: # ignored by PrepareAndDispatch, so no need to save it here. 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: la t9, PrepareAndDispatch michael@0: michael@0: # t0 is methodIndex michael@0: move a1, t0 michael@0: # have a2 point to the begin of the argument space on stack michael@0: addiu a2, sp, FRAMESZ michael@0: michael@0: # PrepareAndDispatch(that, methodIndex, args) michael@0: jalr t9 michael@0: michael@0: # Micro-optimization: Using jalr explicitly has the side-effect michael@0: # of not triggering .cprestore. This is ok because we have no michael@0: # gp reference below this point. It also allows better michael@0: # instruction sscheduling. michael@0: # lw gp, GPOFF(fp) michael@0: michael@0: lw ra, RAOFF(sp) michael@0: addiu sp, FRAMESZ michael@0: j ra michael@0: END(dummy)