| 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 | * |
|---|
| 28 | * Alternatively, the contents of this file may be used under the terms of |
|---|
| 29 | * either the GNU General Public License Version 2 or later (the "GPL"), or |
|---|
| 30 | * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), |
|---|
| 31 | * in which case the provisions of the GPL or the LGPL are applicable instead |
|---|
| 32 | * of those above. If you wish to allow use of your version of this file only |
|---|
| 33 | * under the terms of either the GPL or the LGPL, and not to allow others to |
|---|
| 34 | * use your version of this file under the terms of the MPL, indicate your |
|---|
| 35 | * decision by deleting the provisions above and replace them with the notice |
|---|
| 36 | * and other provisions required by the GPL or the LGPL. If you do not delete |
|---|
| 37 | * the provisions above, a recipient may use your version of this file under |
|---|
| 38 | * the terms of any one of the MPL, the GPL or the LGPL. |
|---|
| 39 | * |
|---|
| 40 | * ***** END LICENSE BLOCK ***** */ |
|---|
| 41 | |
|---|
| 42 | /* This code is for MIPS using the O32 ABI. */ |
|---|
| 43 | |
|---|
| 44 | #include <sys/regdef.h> |
|---|
| 45 | #include <sys/asm.h> |
|---|
| 46 | |
|---|
| 47 | .text |
|---|
| 48 | .globl invoke_count_words |
|---|
| 49 | .globl invoke_copy_to_stack |
|---|
| 50 | |
|---|
| 51 | # We need a variable number of words allocated from the stack for copies of |
|---|
| 52 | # the params, and this space must come between the high frame (where ra, gp, |
|---|
| 53 | # and s0 are saved) and the low frame (where a0-a3 are saved by the callee |
|---|
| 54 | # functions we invoke). |
|---|
| 55 | |
|---|
| 56 | LOCALSZ=4 # s0, s1, ra, gp |
|---|
| 57 | NARGSAVE=4 # a0, a1, a2, a3 |
|---|
| 58 | HIFRAMESZ=(LOCALSZ*SZREG) |
|---|
| 59 | LOFRAMESZ=(NARGSAVE*SZREG) |
|---|
| 60 | FRAMESZ=(HIFRAMESZ+LOFRAMESZ+ALSZ)&ALMASK |
|---|
| 61 | |
|---|
| 62 | # XXX these 2*SZREG, etc. are very magic -- we *know* that ALSZ&ALMASK cause |
|---|
| 63 | # FRAMESZ to be 0 mod 8, in this case to be 16 and not 12. |
|---|
| 64 | RAOFF=FRAMESZ - (2*SZREG) |
|---|
| 65 | GPOFF=FRAMESZ - (3*SZREG) |
|---|
| 66 | S0OFF=FRAMESZ - (4*SZREG) |
|---|
| 67 | S1OFF=FRAMESZ - (5*SZREG) |
|---|
| 68 | |
|---|
| 69 | # These are not magic -- they are just our argsave slots in the caller frame. |
|---|
| 70 | A0OFF=FRAMESZ |
|---|
| 71 | A1OFF=FRAMESZ + (1*SZREG) |
|---|
| 72 | A2OFF=FRAMESZ + (2*SZREG) |
|---|
| 73 | A3OFF=FRAMESZ + (3*SZREG) |
|---|
| 74 | |
|---|
| 75 | # |
|---|
| 76 | # _XPTC_InvokeByIndex(that, methodIndex, paramCount, params) |
|---|
| 77 | # a0 a1 a2 a3 |
|---|
| 78 | |
|---|
| 79 | NESTED(_XPTC_InvokeByIndex, FRAMESZ, ra) |
|---|
| 80 | |
|---|
| 81 | .set noreorder |
|---|
| 82 | .cpload t9 |
|---|
| 83 | .set reorder |
|---|
| 84 | |
|---|
| 85 | subu sp, FRAMESZ |
|---|
| 86 | |
|---|
| 87 | # specify the save register mask -- XXX do we want the a0-a3 here, given |
|---|
| 88 | # our "split" frame where the args are saved below a dynamicly allocated |
|---|
| 89 | # region under the high frame? |
|---|
| 90 | # |
|---|
| 91 | # 10010000000000010000000011110000 |
|---|
| 92 | .mask 0x900100F0, -((NARGSAVE+LOCALSZ)*SZREG) |
|---|
| 93 | |
|---|
| 94 | # thou shalt not use .cprestore if yer frame has variable size... |
|---|
| 95 | # .cprestore GPOFF |
|---|
| 96 | |
|---|
| 97 | REG_S ra, RAOFF(sp) |
|---|
| 98 | |
|---|
| 99 | # this happens automatically with .cprestore, but we cannot use that op... |
|---|
| 100 | REG_S gp, GPOFF(sp) |
|---|
| 101 | REG_S s0, S0OFF(sp) |
|---|
| 102 | REG_S s1, S1OFF(sp) |
|---|
| 103 | |
|---|
| 104 | REG_S a0, A0OFF(sp) |
|---|
| 105 | REG_S a1, A1OFF(sp) |
|---|
| 106 | REG_S a2, A2OFF(sp) |
|---|
| 107 | REG_S a3, A3OFF(sp) |
|---|
| 108 | |
|---|
| 109 | # invoke_count_words(paramCount, params) |
|---|
| 110 | move a0, a2 |
|---|
| 111 | move a1, a3 |
|---|
| 112 | |
|---|
| 113 | jal invoke_count_words |
|---|
| 114 | lw gp, GPOFF(sp) |
|---|
| 115 | |
|---|
| 116 | # save the old sp so we can pop the param area and any "low frame" |
|---|
| 117 | # needed as an argsave area below the param block for callees that |
|---|
| 118 | # we invoke. |
|---|
| 119 | move s0, sp |
|---|
| 120 | |
|---|
| 121 | REG_L a1, A2OFF(sp) # a1 = paramCount |
|---|
| 122 | REG_L a2, A3OFF(sp) # a2 = params |
|---|
| 123 | |
|---|
| 124 | # we define a word as 4 bytes, period end of story! |
|---|
| 125 | sll v0, 2 # 4 bytes * result of invoke_copy_words |
|---|
| 126 | subu v0, LOFRAMESZ # but we take back the argsave area built into |
|---|
| 127 | # our stack frame -- SWEET! |
|---|
| 128 | subu sp, sp, v0 # make room |
|---|
| 129 | move a0, sp # a0 = param stack address |
|---|
| 130 | move s1, a0 # save it for later -- it should be safe here |
|---|
| 131 | |
|---|
| 132 | # the old sp is still saved in s0, but we now need another argsave |
|---|
| 133 | # area ("low frame") for the invoke_copy_to_stack call. |
|---|
| 134 | subu sp, sp, LOFRAMESZ |
|---|
| 135 | |
|---|
| 136 | # copy the param into the stack areas |
|---|
| 137 | # invoke_copy_to_stack(PRUint32* d, PRUint32 paramCount, |
|---|
| 138 | # nsXPTCVariant* s) |
|---|
| 139 | jal invoke_copy_to_stack |
|---|
| 140 | lw gp, GPOFF(s0) |
|---|
| 141 | |
|---|
| 142 | move sp, s0 # get orig sp back, popping params and argsave |
|---|
| 143 | |
|---|
| 144 | REG_L a0, A0OFF(sp) # a0 = set "that" to be "this" |
|---|
| 145 | REG_L a1, A1OFF(sp) # a1 = methodIndex |
|---|
| 146 | |
|---|
| 147 | # t1 = methodIndex * 4 |
|---|
| 148 | # (use shift instead of mult) |
|---|
| 149 | sll t1, a1, 2 |
|---|
| 150 | |
|---|
| 151 | # calculate the function we need to jump to, |
|---|
| 152 | # which must then be saved in t9 |
|---|
| 153 | lw t9, 0(a0) |
|---|
| 154 | addu t9, t9, t1 |
|---|
| 155 | lw t9, 8(t9) |
|---|
| 156 | |
|---|
| 157 | # a1..a3 and f13..f14 should now be set to what |
|---|
| 158 | # invoke_copy_to_stack told us. skip a0 and f12 |
|---|
| 159 | # because that is the "this" pointer |
|---|
| 160 | |
|---|
| 161 | REG_L a1, 1*SZREG(s1) |
|---|
| 162 | REG_L a2, 2*SZREG(s1) |
|---|
| 163 | REG_L a3, 3*SZREG(s1) |
|---|
| 164 | |
|---|
| 165 | l.d $f13, 8(s1) |
|---|
| 166 | l.d $f14, 16(s1) |
|---|
| 167 | |
|---|
| 168 | # Create the stack pointer for the function, which must have 4 words |
|---|
| 169 | # of space for callee-saved args. invoke_count_words allocated space |
|---|
| 170 | # for a0 starting at s1, so we just move s1 into sp. |
|---|
| 171 | move sp, s1 |
|---|
| 172 | |
|---|
| 173 | jalr ra, t9 |
|---|
| 174 | lw gp, GPOFF(s0) |
|---|
| 175 | |
|---|
| 176 | move sp, s0 |
|---|
| 177 | |
|---|
| 178 | REG_L ra, RAOFF(sp) |
|---|
| 179 | REG_L s0, S0OFF(sp) |
|---|
| 180 | addu sp, FRAMESZ |
|---|
| 181 | j ra |
|---|
| 182 | .end _XPTC_InvokeByIndex |
|---|