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