1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ipf64.s Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,146 @@ 1.4 + 1.5 +// Select C numeric constant 1.6 + .radix C 1.7 +// for 64 bit mode, use .psr abi64 1.8 + .psr abi64 1.9 +// little endian 1.10 + .psr lsb 1.11 +// Section has executable code 1.12 + .section .text, "ax","progbits" 1.13 +// procedure named 'NS_InvokeByIndex' 1.14 + .proc NS_InvokeByIndex 1.15 +// manual bundling 1.16 + .explicit 1.17 + 1.18 +// extern "C" uint32_t 1.19 +// invoke_copy_to_stack(uint64_t* d, 1.20 +// const uint32_t paramCount, nsXPTCVariant* s) 1.21 + .global invoke_copy_to_stack 1.22 +// .exclass invoke_copy_to_stack, @fullyvisible 1.23 + .type invoke_copy_to_stack,@function 1.24 + 1.25 +// .exclass NS_InvokeByIndex, @fullyvisible 1.26 + .type NS_InvokeByIndex,@function 1.27 + 1.28 +// XPTC_InvokeByIndex(nsISupports* that, uint32_t methodIndex, 1.29 +// uint32_t paramCount, nsXPTCVariant* params); 1.30 +NS_InvokeByIndex:: 1.31 + .prologue 1.32 + .save ar.pfs, r37 1.33 +// allocate 4 input args, 6 local args, and 8 output args 1.34 + alloc r37 = ar.pfs, 4, 6, 8, 0 // M 1.35 + nop.i 0 ;; // I 1.36 + 1.37 +// unwind table already knows gp, no need to specify anything 1.38 + add r39 = 0, gp // A 1.39 + .save rp, r36 1.40 + mov r36 = rp // I 1.41 + .vframe r38 1.42 + add r38 = 0, sp ;; // A 1.43 + 1.44 +// We first calculate the amount of extra memory stack space required 1.45 +// for the arguments, and register storage. 1.46 +// We then call invoke_copy_to_stack() to write the argument contents 1.47 +// to the specified memory regions. 1.48 +// We then copy the integer arguments to integer registers, and floating 1.49 +// arguments to float registers. 1.50 +// Lastly we load the virtual table jump pointer, and call the target 1.51 +// subroutine. 1.52 + 1.53 +// in0 : that 1.54 +// in1 : methodIndex 1.55 +// in2 : paramCount 1.56 +// in3 : params 1.57 + 1.58 +// stack frame size is 16 + (8 * even(paramCount)) + 64 + 64 1.59 +// 16 byte frame header 1.60 +// 8 * even(paramCount) memory argument area 1.61 +// 64 bytes integer register area 1.62 +// 64 bytes float register area 1.63 +// This scheme makes sure stack fram size is a multiple of 16 1.64 + 1.65 + .body 1.66 + add r10 = 8, r0 // A 1.67 +// r41 points to float register area 1.68 + add r41 = -64, sp // A 1.69 +// r40 points to int register area 1.70 + add r40 = -128, sp ;; // A 1.71 + 1.72 + add out1 = 0, r40 // A 1.73 + add out2 = 0, r41 // A 1.74 + tbit.z p14,p15 = in2,0 ;; // I 1.75 + 1.76 +// compute 8 * even(paramCount) 1.77 +(p14) shladd r11 = in2, 3, r0 ;; // A 1.78 +(p15) shladd r11 = in2, 3, r10 ;; // A 1.79 + sub out0 = r40, r11 ;; // A 1.80 + 1.81 +// advance the stack frame 1.82 + add sp = -16, out0 // A 1.83 + add out3 = 0, in2 // A 1.84 + add out4 = 0, in3 // A 1.85 + 1.86 +// branch to invoke_copy_to_stack 1.87 + br.call.sptk.few rp = invoke_copy_to_stack ;; // B 1.88 + 1.89 +// restore gp 1.90 + add gp = 0, r39 // A 1.91 + add out0 = 0, in0 // A 1.92 + 1.93 +// load the integer and float registers 1.94 + ld8 out1 = [r40], 8 // M 1.95 + ldfd f8 = [r41], 8 ;; // M 1.96 + 1.97 + ld8 out2 = [r40], 8 // M 1.98 + ldfd f9 = [r41], 8 ;; // M 1.99 + 1.100 + ld8 out3 = [r40], 8 // M 1.101 + ldfd f10 = [r41], 8 ;; // M 1.102 + 1.103 + ld8 out4 = [r40], 8 // M 1.104 + ldfd f11 = [r41], 8 ;; // M 1.105 + 1.106 + ld8 out5 = [r40], 8 // M 1.107 + ldfd f12 = [r41], 8 ;; // M 1.108 +// 16 * methodIndex 1.109 + shladd r11 = in1, 4, r0 // A 1.110 + 1.111 + ld8 out6 = [r40], 8 // M 1.112 + ldfd f13 = [r41], 8 ;; // M 1.113 + 1.114 + ld8 out7 = [r40], 8 // M 1.115 + ldfd f14 = [r41], 8 // M 1.116 + add r8 = 0, in0 ;; // A 1.117 + 1.118 +// look up virtual base table and dispatch to target subroutine 1.119 +// This section assumes 64 bit pointer mode, and virtual base table 1.120 +// layout from the ABI http://www.codesourcery.com/cxx-abi/abi.html 1.121 + 1.122 +// load base table 1.123 + ld8 r8 = [r8] ;; // M 1.124 + add r8 = r11, r8 ;; // A 1.125 + 1.126 + // first entry is jump pointer, second entry is gp 1.127 + add r9 = 8, r8 ;; // A 1.128 +// load jump pointer 1.129 + ld8 r8 = [r8] 1.130 + 1.131 +// load gp 1.132 + ld8 gp = [r9] ;; // M 1.133 + mov b6 = r8 ;; // I 1.134 + 1.135 +// branch to target virtual function 1.136 + br.call.sptk.few rp = b6 ;; // B 1.137 + 1.138 +// epilog 1.139 + mov ar.pfs = r37 // I 1.140 + mov rp = r36 ;; // I 1.141 + 1.142 + add sp = 0, r38 // A 1.143 + add gp = 0, r39 // A 1.144 + br.ret.sptk.few rp ;; // B 1.145 + 1.146 + .endp 1.147 + 1.148 +/* Magic indicating no need for an executable stack */ 1.149 +.section .note.GNU-stack, "", @progbits ; .previous