2
// Select C numeric constant
4
// for 64 bit mode, use .psr abi64
8
// Section has executable code
9
.section .text, "ax","progbits"
10
// procedure named 'XPTC_InvokeByIndex'
11
.proc XPTC_InvokeByIndex
15
// extern "C" PRUint32
16
// invoke_copy_to_stack(uint64_t* d,
17
// const PRUint32 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 XPTC_InvokeByIndex, @fullyvisible
23
.type XPTC_InvokeByIndex,@function
25
// XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex,
26
// PRUint32 paramCount, nsXPTCVariant* params);
30
// allocate 4 input args, 6 local args, and 8 output args
31
alloc r37 = ar.pfs, 4, 6, 8, 0 // M
34
// unwind table already knows gp, no need to specify anything
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
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
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
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
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
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
129
ld8 gp = [r9] ;; // M
132
// branch to target virtual function
133
br.call.sptk.few rp = b6 ;; // B
136
mov ar.pfs = r37 // I
141
br.ret.sptk.few rp ;; // B