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
2 // Select C numeric constant
3 .radix C
4 // for 64 bit mode, use .psr abi64
5 .psr abi32
6 // big endian
7 .psr msb
8 // Section has executable code
9 .section .text, "ax","progbits"
10 // procedure named 'NS_InvokeByIndex'
11 .proc NS_InvokeByIndex
12 // manual bundling
13 .explicit
15 // extern "C" uint32_t
16 // invoke_copy_to_stack(uint64_t* d,
17 // const uint32_t paramCount, nsXPTCVariant* s)
18 .global invoke_copy_to_stack
19 // .exclass invoke_copy_to_stack, @fullyvisible
20 .type invoke_copy_to_stack,@function
22 // .exclass NS_InvokeByIndex, @fullyvisible
23 .type NS_InvokeByIndex,@function
25 // NS_InvokeByIndex(nsISupports* that, uint32_t methodIndex,
26 // uint32_t paramCount, nsXPTCVariant* params);
27 NS_InvokeByIndex::
28 .prologue
29 .save ar.pfs, r37
30 // allocate 4 input args, 6 local args, and 8 output args
31 alloc r37 = ar.pfs, 4, 6, 8, 0 // M
32 nop.i 0 ;; // I
34 // unwind table already knows gp, no need to specify anything
35 add r39 = 0, gp // A
36 .save rp, r36
37 mov r36 = rp // I
38 .vframe r38
39 add r38 = 0, sp ;; // A
41 // We first calculate the amount of extra memory stack space required
42 // for the arguments, and register storage.
43 // We then call invoke_copy_to_stack() to write the argument contents
44 // to the specified memory regions.
45 // We then copy the integer arguments to integer registers, and floating
46 // arguments to float registers.
47 // Lastly we load the virtual table jump pointer, and call the target
48 // subroutine.
50 // in0 : that
51 // in1 : methodIndex
52 // in2 : paramCount
53 // in3 : params
55 // stack frame size is 16 + (8 * even(paramCount)) + 64 + 64
56 // 16 byte frame header
57 // 8 * even(paramCount) memory argument area
58 // 64 bytes integer register area
59 // 64 bytes float register area
60 // This scheme makes sure stack fram size is a multiple of 16
62 .body
63 add r10 = 8, r0 // A
64 // r41 points to float register area
65 add r41 = -64, sp // A
66 // r40 points to int register area
67 add r40 = -128, sp ;; // A
69 add out1 = 0, r40 // A
70 add out2 = 0, r41 // A
71 tbit.z p14,p15 = in2,0 ;; // I
73 // compute 8 * even(paramCount)
74 (p14) shladd r11 = in2, 3, r0 ;; // A
75 (p15) shladd r11 = in2, 3, r10 ;; // A
76 sub out0 = r40, r11 ;; // A
78 // advance the stack frame
79 add sp = -16, out0 // A
80 add out3 = 0, in2 // A
81 add out4 = 0, in3 // A
83 // branch to invoke_copy_to_stack
84 br.call.sptk.few rp = invoke_copy_to_stack ;; // B
86 // restore gp
87 add gp = 0, r39 // A
88 add out0 = 0, in0 // A
90 // load the integer and float registers
91 ld8 out1 = [r40], 8 // M
92 ldfd f8 = [r41], 8 ;; // M
94 ld8 out2 = [r40], 8 // M
95 ldfd f9 = [r41], 8 ;; // M
97 ld8 out3 = [r40], 8 // M
98 ldfd f10 = [r41], 8 ;; // M
100 ld8 out4 = [r40], 8 // M
101 ldfd f11 = [r41], 8 ;; // M
103 ld8 out5 = [r40], 8 // M
104 ldfd f12 = [r41], 8 ;; // M
105 // 16 * methodIndex
106 shladd r11 = in1, 4, r0 // A
108 ld8 out6 = [r40], 8 // M
109 ldfd f13 = [r41], 8 ;; // M
111 ld8 out7 = [r40], 8 // M
112 ldfd f14 = [r41], 8 // M
113 addp4 r8 = 0, in0 ;; // A
115 // look up virtual base table and dispatch to target subroutine
116 // This section assumes 32 bit pointer mode, and virtual base table
117 // layout from the ABI http://www.codesourcery.com/cxx-abi/abi.html
119 // load base table
120 ld4 r8 = [r8] ;; // M
121 addp4 r8 = r11, r8 ;; // A
123 // first entry is jump pointer, second entry is gp
124 addp4 r9 = 8, r8 ;; // A
125 // load jump pointer
126 ld8 r8 = [r8]
128 // load gp
129 ld8 gp = [r9] ;; // M
130 mov b6 = r8 ;; // I
132 // branch to target virtual function
133 br.call.sptk.few rp = b6 ;; // B
135 // epilog
136 mov ar.pfs = r37 // I
137 mov rp = r36 ;; // I
139 add sp = 0, r38 // A
140 add gp = 0, r39 // A
141 br.ret.sptk.few rp ;; // B
143 .endp