| 1 | /* -*- Mode: asm; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- |
|---|
| 2 | * Version: MPL 1.1 |
|---|
| 3 | * |
|---|
| 4 | * ***** BEGIN LICENSE BLOCK ***** |
|---|
| 5 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
|---|
| 6 | * |
|---|
| 7 | * The contents of this file are subject to the Mozilla Public License Version |
|---|
| 8 | * 1.1 (the "License"); you may not use this file except in compliance with |
|---|
| 9 | * the License. You may obtain a copy of the License at |
|---|
| 10 | * http://www.mozilla.org/MPL/ |
|---|
| 11 | * |
|---|
| 12 | * Software distributed under the License is distributed on an "AS IS" basis, |
|---|
| 13 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
|---|
| 14 | * for the specific language governing rights and limitations under the |
|---|
| 15 | * License. |
|---|
| 16 | * |
|---|
| 17 | * The Original Code is mozilla.org code. |
|---|
| 18 | * |
|---|
| 19 | * The Initial Developer of the Original Code is |
|---|
| 20 | * Netscape Communications Corp, Inc. |
|---|
| 21 | * Portions created by the Initial Developer are Copyright (C) 2001 |
|---|
| 22 | * the Initial Developer. All Rights Reserved. |
|---|
| 23 | * |
|---|
| 24 | * Contributor(s): |
|---|
| 25 | * Brendan Eich <brendan@mozilla.org> |
|---|
| 26 | * Stuart Parmenter <pavlov@netscape.com> |
|---|
| 27 | * Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de> |
|---|
| 28 | * |
|---|
| 29 | * Alternatively, the contents of this file may be used under the terms of |
|---|
| 30 | * either the GNU General Public License Version 2 or later (the "GPL"), or |
|---|
| 31 | * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), |
|---|
| 32 | * in which case the provisions of the GPL or the LGPL are applicable instead |
|---|
| 33 | * of those above. If you wish to allow use of your version of this file only |
|---|
| 34 | * under the terms of either the GPL or the LGPL, and not to allow others to |
|---|
| 35 | * use your version of this file under the terms of the MPL, indicate your |
|---|
| 36 | * decision by deleting the provisions above and replace them with the notice |
|---|
| 37 | * and other provisions required by the GPL or the LGPL. If you do not delete |
|---|
| 38 | * the provisions above, a recipient may use your version of this file under |
|---|
| 39 | * the terms of any one of the MPL, the GPL or the LGPL. |
|---|
| 40 | * |
|---|
| 41 | * ***** END LICENSE BLOCK ***** */ |
|---|
| 42 | |
|---|
| 43 | /* This code is for MIPS using the O32 ABI. */ |
|---|
| 44 | |
|---|
| 45 | #include <sys/regdef.h> |
|---|
| 46 | #include <sys/asm.h> |
|---|
| 47 | |
|---|
| 48 | # NARGSAVE is the argument space in the callers frame, including extra |
|---|
| 49 | # 'shadowed' space for the argument registers. The minimum of 4 |
|---|
| 50 | # argument slots is sometimes predefined in the header files. |
|---|
| 51 | #ifndef NARGSAVE |
|---|
| 52 | #define NARGSAVE 4 |
|---|
| 53 | #endif |
|---|
| 54 | |
|---|
| 55 | #define LOCALSZ 3 /* gp, fp, ra */ |
|---|
| 56 | #define FRAMESZ ((((NARGSAVE+LOCALSZ)*SZREG)+ALSZ)&ALMASK) |
|---|
| 57 | |
|---|
| 58 | #define RAOFF (FRAMESZ - (1*SZREG)) |
|---|
| 59 | #define FPOFF (FRAMESZ - (2*SZREG)) |
|---|
| 60 | #define GPOFF (FRAMESZ - (3*SZREG)) |
|---|
| 61 | |
|---|
| 62 | #define A0OFF (FRAMESZ + (0*SZREG)) |
|---|
| 63 | #define A1OFF (FRAMESZ + (1*SZREG)) |
|---|
| 64 | #define A2OFF (FRAMESZ + (2*SZREG)) |
|---|
| 65 | #define A3OFF (FRAMESZ + (3*SZREG)) |
|---|
| 66 | |
|---|
| 67 | .text |
|---|
| 68 | |
|---|
| 69 | # |
|---|
| 70 | # _NS_InvokeByIndex_P(that, methodIndex, paramCount, params) |
|---|
| 71 | # a0 a1 a2 a3 |
|---|
| 72 | |
|---|
| 73 | .globl _NS_InvokeByIndex_P |
|---|
| 74 | .align 2 |
|---|
| 75 | .type _NS_InvokeByIndex_P,@function |
|---|
| 76 | .ent _NS_InvokeByIndex_P,0 |
|---|
| 77 | .frame fp, FRAMESZ, ra |
|---|
| 78 | _NS_InvokeByIndex_P: |
|---|
| 79 | SETUP_GP |
|---|
| 80 | subu sp, FRAMESZ |
|---|
| 81 | |
|---|
| 82 | # specify the save register mask for gp, fp, ra, a3 - a0 |
|---|
| 83 | .mask 0xD00000F0, RAOFF-FRAMESZ |
|---|
| 84 | |
|---|
| 85 | sw ra, RAOFF(sp) |
|---|
| 86 | sw fp, FPOFF(sp) |
|---|
| 87 | |
|---|
| 88 | # we can't use .cprestore in a variable stack frame |
|---|
| 89 | sw gp, GPOFF(sp) |
|---|
| 90 | |
|---|
| 91 | sw a0, A0OFF(sp) |
|---|
| 92 | sw a1, A1OFF(sp) |
|---|
| 93 | sw a2, A2OFF(sp) |
|---|
| 94 | sw a3, A3OFF(sp) |
|---|
| 95 | |
|---|
| 96 | # save bottom of fixed frame |
|---|
| 97 | move fp, sp |
|---|
| 98 | |
|---|
| 99 | # extern "C" uint32 |
|---|
| 100 | # invoke_count_words(PRUint32 paramCount, nsXPTCVariant* s); |
|---|
| 101 | la t9, invoke_count_words |
|---|
| 102 | move a0, a2 |
|---|
| 103 | move a1, a3 |
|---|
| 104 | jalr t9 |
|---|
| 105 | lw gp, GPOFF(fp) |
|---|
| 106 | |
|---|
| 107 | # allocate variable stack, with a size of: |
|---|
| 108 | # wordsize (of 4 bytes) * result (already aligned to dword) |
|---|
| 109 | # but a minimum of 16 byte |
|---|
| 110 | sll v0, 2 |
|---|
| 111 | slt t0, v0, 16 |
|---|
| 112 | beqz t0, 1f |
|---|
| 113 | li v0, 16 |
|---|
| 114 | 1: subu sp, v0 |
|---|
| 115 | |
|---|
| 116 | # let a0 point to the bottom of the variable stack, allocate |
|---|
| 117 | # another fixed stack for: |
|---|
| 118 | # extern "C" void |
|---|
| 119 | # invoke_copy_to_stack(PRUint32* d, PRUint32 paramCount, |
|---|
| 120 | # nsXPTCVariant* s); |
|---|
| 121 | la t9, invoke_copy_to_stack |
|---|
| 122 | move a0, sp |
|---|
| 123 | lw a1, A2OFF(fp) |
|---|
| 124 | lw a2, A3OFF(fp) |
|---|
| 125 | subu sp, 16 |
|---|
| 126 | jalr t9 |
|---|
| 127 | lw gp, GPOFF(fp) |
|---|
| 128 | |
|---|
| 129 | # back to the variable stack frame |
|---|
| 130 | addu sp, 16 |
|---|
| 131 | |
|---|
| 132 | # calculate the function we need to jump to, which must then be |
|---|
| 133 | # stored in t9 |
|---|
| 134 | lw a0, A0OFF(fp) # a0 = set "that" to be "this" |
|---|
| 135 | lw t0, A1OFF(fp) # a1 = methodIndex |
|---|
| 136 | lw t9, 0(a0) |
|---|
| 137 | # t0 = methodIndex << PTRLOG |
|---|
| 138 | sll t0, t0, PTRLOG |
|---|
| 139 | addu t9, t0 |
|---|
| 140 | #if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100 /* G++ V3 ABI */ |
|---|
| 141 | lw t9, (t9) |
|---|
| 142 | #else /* not G++ V3 ABI */ |
|---|
| 143 | lw t9, 2*PTRSIZE(t9) |
|---|
| 144 | #endif /* G++ V3 ABI */ |
|---|
| 145 | |
|---|
| 146 | # Set a1-a3 to what invoke_copy_to_stack told us. a0 is already |
|---|
| 147 | # the "this" pointer. We don't have to care about floating |
|---|
| 148 | # point arguments, the non-FP "this" pointer as first argument |
|---|
| 149 | # means they'll never be used. |
|---|
| 150 | lw a1, 1*SZREG(sp) |
|---|
| 151 | lw a2, 2*SZREG(sp) |
|---|
| 152 | lw a3, 3*SZREG(sp) |
|---|
| 153 | |
|---|
| 154 | jalr t9 |
|---|
| 155 | # Micro-optimization: There's no gp usage below this point, so |
|---|
| 156 | # we don't reload. |
|---|
| 157 | # lw gp, GPOFF(fp) |
|---|
| 158 | |
|---|
| 159 | # leave variable stack frame |
|---|
| 160 | move sp, fp |
|---|
| 161 | |
|---|
| 162 | lw ra, RAOFF(sp) |
|---|
| 163 | lw fp, FPOFF(sp) |
|---|
| 164 | |
|---|
| 165 | addiu sp, FRAMESZ |
|---|
| 166 | j ra |
|---|
| 167 | END(_NS_InvokeByIndex_P) |
|---|