|
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 #include <sys/regdef.h> |
|
6 #include <sys/asm.h> |
|
7 |
|
8 .text |
|
9 .globl invoke_count_words |
|
10 .globl invoke_copy_to_stack |
|
11 |
|
12 LOCALSZ=7 # a0, a1, a2, a3, s0, ra, gp |
|
13 FRAMESZ=(((NARGSAVE+LOCALSZ)*SZREG)+ALSZ)&ALMASK |
|
14 |
|
15 RAOFF=FRAMESZ-(1*SZREG) |
|
16 A0OFF=FRAMESZ-(2*SZREG) |
|
17 A1OFF=FRAMESZ-(3*SZREG) |
|
18 A2OFF=FRAMESZ-(4*SZREG) |
|
19 A3OFF=FRAMESZ-(5*SZREG) |
|
20 S0OFF=FRAMESZ-(6*SZREG) |
|
21 GPOFF=FRAMESZ-(7*SZREG) |
|
22 |
|
23 # |
|
24 # _NS_InvokeByIndex(that, methodIndex, paramCount, params) |
|
25 # a0 a1 a2 a3 |
|
26 |
|
27 NESTED(_NS_InvokeByIndex, FRAMESZ, ra) |
|
28 PTR_SUBU sp, FRAMESZ |
|
29 SETUP_GP64(GPOFF, _NS_InvokeByIndex) |
|
30 |
|
31 REG_S ra, RAOFF(sp) |
|
32 REG_S a0, A0OFF(sp) |
|
33 REG_S a1, A1OFF(sp) |
|
34 REG_S a2, A2OFF(sp) |
|
35 REG_S a3, A3OFF(sp) |
|
36 REG_S s0, S0OFF(sp) |
|
37 |
|
38 # invoke_count_words(paramCount, params) |
|
39 move a0, a2 |
|
40 move a1, a3 |
|
41 jal invoke_count_words |
|
42 |
|
43 # invoke_copy_to_stack(uint32_t* d, uint32_t paramCount, |
|
44 # nsXPTCVariant* s, uint32_t *reg) |
|
45 |
|
46 REG_L a1, A2OFF(sp) # a1 - paramCount |
|
47 REG_L a2, A3OFF(sp) # a2 - params |
|
48 |
|
49 # save sp before we copy the params to the stack |
|
50 move t0, sp |
|
51 |
|
52 # assume full size of 16 bytes per param to be safe |
|
53 sll v0, 4 # 16 bytes * num params |
|
54 subu sp, sp, v0 # make room |
|
55 move a0, sp # a0 - param stack address |
|
56 |
|
57 # create temporary stack space to write int and fp regs |
|
58 subu sp, 64 # 64 = 8 regs of 8 bytes |
|
59 move a3, sp |
|
60 |
|
61 # save the old sp and save the arg stack |
|
62 subu sp, sp, 16 |
|
63 REG_S t0, 0(sp) |
|
64 REG_S a0, 8(sp) |
|
65 |
|
66 # copy the param into the stack areas |
|
67 jal invoke_copy_to_stack |
|
68 |
|
69 REG_L t3, 8(sp) # get previous a0 |
|
70 REG_L sp, 0(sp) # get orig sp back |
|
71 |
|
72 REG_L a0, A0OFF(sp) # a0 - that |
|
73 REG_L a1, A1OFF(sp) # a1 - methodIndex |
|
74 |
|
75 # t1 = methodIndex * pow(2, PTRLOG) |
|
76 # (use shift instead of mult) |
|
77 sll t1, a1, PTRLOG |
|
78 |
|
79 # calculate the function we need to jump to, |
|
80 # which must then be saved in t9 |
|
81 lw t9, 0(a0) |
|
82 addu t9, t9, t1 |
|
83 lw t9, (t9) |
|
84 |
|
85 # get register save area from invoke_copy_to_stack |
|
86 subu t1, t3, 64 |
|
87 |
|
88 # a1..a7 and f13..f19 should now be set to what |
|
89 # invoke_copy_to_stack told us. skip a0 and f12 |
|
90 # because that's the "this" pointer |
|
91 |
|
92 REG_L a1, 0(t1) |
|
93 REG_L a2, 8(t1) |
|
94 REG_L a3, 16(t1) |
|
95 REG_L a4, 24(t1) |
|
96 REG_L a5, 32(t1) |
|
97 REG_L a6, 40(t1) |
|
98 REG_L a7, 48(t1) |
|
99 |
|
100 l.d $f13, 0(t1) |
|
101 l.d $f14, 8(t1) |
|
102 l.d $f15, 16(t1) |
|
103 l.d $f16, 24(t1) |
|
104 l.d $f17, 32(t1) |
|
105 l.d $f18, 40(t1) |
|
106 l.d $f19, 48(t1) |
|
107 |
|
108 # save away our stack pointer and create |
|
109 # the stack pointer for the function |
|
110 move s0, sp |
|
111 move sp, t3 |
|
112 |
|
113 jalr t9 |
|
114 |
|
115 move sp, s0 |
|
116 |
|
117 RESTORE_GP64 |
|
118 REG_L ra, RAOFF(sp) |
|
119 REG_L s0, S0OFF(sp) |
|
120 PTR_ADDU sp, FRAMESZ |
|
121 j ra |
|
122 .end _NS_InvokeByIndex |