|
1 |
|
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 |
|
14 |
|
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 |
|
21 |
|
22 // .exclass NS_InvokeByIndex, @fullyvisible |
|
23 .type NS_InvokeByIndex,@function |
|
24 |
|
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 |
|
33 |
|
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 |
|
40 |
|
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. |
|
49 |
|
50 // in0 : that |
|
51 // in1 : methodIndex |
|
52 // in2 : paramCount |
|
53 // in3 : params |
|
54 |
|
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 |
|
61 |
|
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 |
|
68 |
|
69 add out1 = 0, r40 // A |
|
70 add out2 = 0, r41 // A |
|
71 tbit.z p14,p15 = in2,0 ;; // I |
|
72 |
|
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 |
|
77 |
|
78 // advance the stack frame |
|
79 add sp = -16, out0 // A |
|
80 add out3 = 0, in2 // A |
|
81 add out4 = 0, in3 // A |
|
82 |
|
83 // branch to invoke_copy_to_stack |
|
84 br.call.sptk.few rp = invoke_copy_to_stack ;; // B |
|
85 |
|
86 // restore gp |
|
87 add gp = 0, r39 // A |
|
88 add out0 = 0, in0 // A |
|
89 |
|
90 // load the integer and float registers |
|
91 ld8 out1 = [r40], 8 // M |
|
92 ldfd f8 = [r41], 8 ;; // M |
|
93 |
|
94 ld8 out2 = [r40], 8 // M |
|
95 ldfd f9 = [r41], 8 ;; // M |
|
96 |
|
97 ld8 out3 = [r40], 8 // M |
|
98 ldfd f10 = [r41], 8 ;; // M |
|
99 |
|
100 ld8 out4 = [r40], 8 // M |
|
101 ldfd f11 = [r41], 8 ;; // M |
|
102 |
|
103 ld8 out5 = [r40], 8 // M |
|
104 ldfd f12 = [r41], 8 ;; // M |
|
105 // 16 * methodIndex |
|
106 shladd r11 = in1, 4, r0 // A |
|
107 |
|
108 ld8 out6 = [r40], 8 // M |
|
109 ldfd f13 = [r41], 8 ;; // M |
|
110 |
|
111 ld8 out7 = [r40], 8 // M |
|
112 ldfd f14 = [r41], 8 // M |
|
113 addp4 r8 = 0, in0 ;; // A |
|
114 |
|
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 |
|
118 |
|
119 // load base table |
|
120 ld4 r8 = [r8] ;; // M |
|
121 addp4 r8 = r11, r8 ;; // A |
|
122 |
|
123 // first entry is jump pointer, second entry is gp |
|
124 addp4 r9 = 8, r8 ;; // A |
|
125 // load jump pointer |
|
126 ld8 r8 = [r8] |
|
127 |
|
128 // load gp |
|
129 ld8 gp = [r9] ;; // M |
|
130 mov b6 = r8 ;; // I |
|
131 |
|
132 // branch to target virtual function |
|
133 br.call.sptk.few rp = b6 ;; // B |
|
134 |
|
135 // epilog |
|
136 mov ar.pfs = r37 // I |
|
137 mov rp = r36 ;; // I |
|
138 |
|
139 add sp = 0, r38 // A |
|
140 add gp = 0, r39 // A |
|
141 br.ret.sptk.few rp ;; // B |
|
142 |
|
143 .endp |
|
144 |
|
145 |