Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
1 # This Source Code Form is subject to the terms of the Mozilla Public
2 # License, v. 2.0. If a copy of the MPL was not distributed with this
3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
5 .set r0,0; .set r1,1; .set r2,2; .set r3,3; .set r4,4
6 .set r5,5; .set r6,6; .set r7,7; .set r8,8; .set r9,9
7 .set r10,10; .set r11,11; .set r12,12; .set r13,13; .set r14,14
8 .set r15,15; .set r16,16; .set r17,17; .set r18,18; .set r19,19
9 .set r20,20; .set r21,21; .set r22,22; .set r23,23; .set r24,24
10 .set r25,25; .set r26,26; .set r27,27; .set r28,28; .set r29,29
11 .set r30,30; .set r31,31
12 .set f0,0; .set f1,1; .set f2,2; .set f3,3; .set f4,4
13 .set f5,5; .set f6,6; .set f7,7; .set f8,8; .set f9,9
14 .set f10,10; .set f11,11; .set f12,12; .set f13,13; .set f14,14
15 .set f15,15; .set f16,16; .set f17,17; .set f18,18; .set f19,19
16 .set f20,20; .set f21,21; .set f22,22; .set f23,23; .set f24,24
17 .set f25,25; .set f26,26; .set f27,27; .set f28,28; .set f29,29
18 .set f30,30; .set f31,31
20 # The ABI defines a fixed stack frame area of 4 doublewords (ELFv2)
21 # or 6 doublewords (ELFv1); the last of these doublewords is used
22 # as TOC pointer save area. The fixed area is followed by a parameter
23 # save area of 8 doublewords (used for vararg routines), followed
24 # by space for parameters passed on the stack.
25 #
26 # We set STACK_TOC to the offset of the TOC pointer save area, and
27 # STACK_PARAMS to the offset of the first on-stack parameter.
29 #if _CALL_ELF == 2
30 #define STACK_TOC 24
31 #define STACK_PARAMS 96
32 #else
33 #define STACK_TOC 40
34 #define STACK_PARAMS 112
35 #endif
37 #
38 # NS_InvokeByIndex(nsISupports* that, uint32_t methodIndex,
39 # uint32_t paramCount, nsXPTCVariant* params)
40 #
42 #if _CALL_ELF == 2
43 .section ".text"
44 .type NS_InvokeByIndex,@function
45 .globl NS_InvokeByIndex
46 .align 2
47 NS_InvokeByIndex:
48 0: addis 2,12,(.TOC.-0b)@ha
49 addi 2,2,(.TOC.-0b)@l
50 .localentry NS_InvokeByIndex,.-NS_InvokeByIndex
51 #else
52 .section ".toc","aw"
53 .section ".text"
54 .align 2
55 .globl NS_InvokeByIndex
56 .section ".opd","aw"
57 .align 3
58 NS_InvokeByIndex:
59 .quad .NS_InvokeByIndex,.TOC.@tocbase
60 .previous
61 .type NS_InvokeByIndex,@function
62 .NS_InvokeByIndex:
63 #endif
64 mflr 0
65 std 0,16(r1)
67 std r29,-24(r1)
68 std r30,-16(r1)
69 std r31,-8(r1)
71 mr r29,r3 # Save 'that' in r29
72 mr r30,r4 # Save 'methodIndex' in r30
73 mr r31,r1 # Save old frame
75 # Allocate stack frame with space for params. Since at least the
76 # first 7 parameters (not including 'that') will be in registers,
77 # we don't actually need stack space for those. We must ensure
78 # that the stack remains 16-byte aligned.
79 #
80 # | (fixed area + | | 7 GP | 13 FP | 3 NV |
81 # | param. save) |(params)........| regs | regs | regs |
82 # (r1)......(+STACK_PARAMS)... (-23*8).(-16*8).(-3*8)..(r31)
84 # +stack frame, -unused stack params, +regs storage, +1 for alignment
85 addi r7,r5,((STACK_PARAMS/8)-7+7+13+3+1)
86 rldicr r7,r7,3,59 # multiply by 8 and mask with ~15
87 neg r7,r7
88 stdux r1,r1,r7
91 # Call invoke_copy_to_stack(uint64_t* gpregs, double* fpregs,
92 # uint32_t paramCount, nsXPTCVariant* s,
93 # uint64_t* d))
95 # r5, r6 are passed through intact (paramCount, params)
96 # r7 (d) has to be r1+STACK_PARAMS
97 # -- where parameters are passed on the stack.
98 # r3, r4 are above that, easier to address from r31 than from r1
100 subi r3,r31,(23*8) # r3 --> GPRS
101 subi r4,r31,(16*8) # r4 --> FPRS
102 addi r7,r1,STACK_PARAMS # r7 --> params
103 bl invoke_copy_to_stack
104 nop
106 # Set up to invoke function
108 ld r9,0(r29) # vtable (r29 is 'that')
109 mr r3,r29 # self is first arg, obviously
111 sldi r30,r30,3 # Find function descriptor
112 add r9,r9,r30
113 ld r12,0(r9)
115 std r2,STACK_TOC(r1) # Save r2 (TOC pointer)
117 #if _CALL_ELF == 2
118 mtctr r12
119 #else
120 ld r0,0(r12) # Actual address from fd.
121 mtctr 0
122 ld r11,16(r12) # Environment pointer from fd.
123 ld r2,8(r12) # TOC pointer from fd.
124 #endif
126 # Load FP and GP registers as required
127 ld r4, -(23*8)(r31)
128 ld r5, -(22*8)(r31)
129 ld r6, -(21*8)(r31)
130 ld r7, -(20*8)(r31)
131 ld r8, -(19*8)(r31)
132 ld r9, -(18*8)(r31)
133 ld r10, -(17*8)(r31)
135 lfd f1, -(16*8)(r31)
136 lfd f2, -(15*8)(r31)
137 lfd f3, -(14*8)(r31)
138 lfd f4, -(13*8)(r31)
139 lfd f5, -(12*8)(r31)
140 lfd f6, -(11*8)(r31)
141 lfd f7, -(10*8)(r31)
142 lfd f8, -(9*8)(r31)
143 lfd f9, -(8*8)(r31)
144 lfd f10, -(7*8)(r31)
145 lfd f11, -(6*8)(r31)
146 lfd f12, -(5*8)(r31)
147 lfd f13, -(4*8)(r31)
149 bctrl # Do it
151 ld r2,STACK_TOC(r1) # Load our own TOC pointer
152 ld r1,0(r1) # Revert stack frame
153 ld 0,16(r1) # Reload lr
154 ld 29,-24(r1) # Restore NVGPRS
155 ld 30,-16(r1)
156 ld 31,-8(r1)
157 mtlr 0
158 blr
160 #if _CALL_ELF == 2
161 .size NS_InvokeByIndex,.-NS_InvokeByIndex
162 #else
163 .size NS_InvokeByIndex,.-.NS_InvokeByIndex
164 #endif
166 # Magic indicating no need for an executable stack
167 .section .note.GNU-stack, "", @progbits ; .previous