1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc64_linux.S Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,167 @@ 1.4 +# This Source Code Form is subject to the terms of the Mozilla Public 1.5 +# License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 +# file, You can obtain one at http://mozilla.org/MPL/2.0/. 1.7 + 1.8 +.set r0,0; .set r1,1; .set r2,2; .set r3,3; .set r4,4 1.9 +.set r5,5; .set r6,6; .set r7,7; .set r8,8; .set r9,9 1.10 +.set r10,10; .set r11,11; .set r12,12; .set r13,13; .set r14,14 1.11 +.set r15,15; .set r16,16; .set r17,17; .set r18,18; .set r19,19 1.12 +.set r20,20; .set r21,21; .set r22,22; .set r23,23; .set r24,24 1.13 +.set r25,25; .set r26,26; .set r27,27; .set r28,28; .set r29,29 1.14 +.set r30,30; .set r31,31 1.15 +.set f0,0; .set f1,1; .set f2,2; .set f3,3; .set f4,4 1.16 +.set f5,5; .set f6,6; .set f7,7; .set f8,8; .set f9,9 1.17 +.set f10,10; .set f11,11; .set f12,12; .set f13,13; .set f14,14 1.18 +.set f15,15; .set f16,16; .set f17,17; .set f18,18; .set f19,19 1.19 +.set f20,20; .set f21,21; .set f22,22; .set f23,23; .set f24,24 1.20 +.set f25,25; .set f26,26; .set f27,27; .set f28,28; .set f29,29 1.21 +.set f30,30; .set f31,31 1.22 + 1.23 +# The ABI defines a fixed stack frame area of 4 doublewords (ELFv2) 1.24 +# or 6 doublewords (ELFv1); the last of these doublewords is used 1.25 +# as TOC pointer save area. The fixed area is followed by a parameter 1.26 +# save area of 8 doublewords (used for vararg routines), followed 1.27 +# by space for parameters passed on the stack. 1.28 +# 1.29 +# We set STACK_TOC to the offset of the TOC pointer save area, and 1.30 +# STACK_PARAMS to the offset of the first on-stack parameter. 1.31 + 1.32 +#if _CALL_ELF == 2 1.33 +#define STACK_TOC 24 1.34 +#define STACK_PARAMS 96 1.35 +#else 1.36 +#define STACK_TOC 40 1.37 +#define STACK_PARAMS 112 1.38 +#endif 1.39 + 1.40 +# 1.41 +# NS_InvokeByIndex(nsISupports* that, uint32_t methodIndex, 1.42 +# uint32_t paramCount, nsXPTCVariant* params) 1.43 +# 1.44 + 1.45 +#if _CALL_ELF == 2 1.46 + .section ".text" 1.47 + .type NS_InvokeByIndex,@function 1.48 + .globl NS_InvokeByIndex 1.49 + .align 2 1.50 +NS_InvokeByIndex: 1.51 +0: addis 2,12,(.TOC.-0b)@ha 1.52 + addi 2,2,(.TOC.-0b)@l 1.53 + .localentry NS_InvokeByIndex,.-NS_InvokeByIndex 1.54 +#else 1.55 + .section ".toc","aw" 1.56 + .section ".text" 1.57 + .align 2 1.58 + .globl NS_InvokeByIndex 1.59 + .section ".opd","aw" 1.60 + .align 3 1.61 +NS_InvokeByIndex: 1.62 + .quad .NS_InvokeByIndex,.TOC.@tocbase 1.63 + .previous 1.64 + .type NS_InvokeByIndex,@function 1.65 +.NS_InvokeByIndex: 1.66 +#endif 1.67 + mflr 0 1.68 + std 0,16(r1) 1.69 + 1.70 + std r29,-24(r1) 1.71 + std r30,-16(r1) 1.72 + std r31,-8(r1) 1.73 + 1.74 + mr r29,r3 # Save 'that' in r29 1.75 + mr r30,r4 # Save 'methodIndex' in r30 1.76 + mr r31,r1 # Save old frame 1.77 + 1.78 + # Allocate stack frame with space for params. Since at least the 1.79 + # first 7 parameters (not including 'that') will be in registers, 1.80 + # we don't actually need stack space for those. We must ensure 1.81 + # that the stack remains 16-byte aligned. 1.82 + # 1.83 + # | (fixed area + | | 7 GP | 13 FP | 3 NV | 1.84 + # | param. save) |(params)........| regs | regs | regs | 1.85 + # (r1)......(+STACK_PARAMS)... (-23*8).(-16*8).(-3*8)..(r31) 1.86 + 1.87 + # +stack frame, -unused stack params, +regs storage, +1 for alignment 1.88 + addi r7,r5,((STACK_PARAMS/8)-7+7+13+3+1) 1.89 + rldicr r7,r7,3,59 # multiply by 8 and mask with ~15 1.90 + neg r7,r7 1.91 + stdux r1,r1,r7 1.92 + 1.93 + 1.94 + # Call invoke_copy_to_stack(uint64_t* gpregs, double* fpregs, 1.95 + # uint32_t paramCount, nsXPTCVariant* s, 1.96 + # uint64_t* d)) 1.97 + 1.98 + # r5, r6 are passed through intact (paramCount, params) 1.99 + # r7 (d) has to be r1+STACK_PARAMS 1.100 + # -- where parameters are passed on the stack. 1.101 + # r3, r4 are above that, easier to address from r31 than from r1 1.102 + 1.103 + subi r3,r31,(23*8) # r3 --> GPRS 1.104 + subi r4,r31,(16*8) # r4 --> FPRS 1.105 + addi r7,r1,STACK_PARAMS # r7 --> params 1.106 + bl invoke_copy_to_stack 1.107 + nop 1.108 + 1.109 + # Set up to invoke function 1.110 + 1.111 + ld r9,0(r29) # vtable (r29 is 'that') 1.112 + mr r3,r29 # self is first arg, obviously 1.113 + 1.114 + sldi r30,r30,3 # Find function descriptor 1.115 + add r9,r9,r30 1.116 + ld r12,0(r9) 1.117 + 1.118 + std r2,STACK_TOC(r1) # Save r2 (TOC pointer) 1.119 + 1.120 +#if _CALL_ELF == 2 1.121 + mtctr r12 1.122 +#else 1.123 + ld r0,0(r12) # Actual address from fd. 1.124 + mtctr 0 1.125 + ld r11,16(r12) # Environment pointer from fd. 1.126 + ld r2,8(r12) # TOC pointer from fd. 1.127 +#endif 1.128 + 1.129 + # Load FP and GP registers as required 1.130 + ld r4, -(23*8)(r31) 1.131 + ld r5, -(22*8)(r31) 1.132 + ld r6, -(21*8)(r31) 1.133 + ld r7, -(20*8)(r31) 1.134 + ld r8, -(19*8)(r31) 1.135 + ld r9, -(18*8)(r31) 1.136 + ld r10, -(17*8)(r31) 1.137 + 1.138 + lfd f1, -(16*8)(r31) 1.139 + lfd f2, -(15*8)(r31) 1.140 + lfd f3, -(14*8)(r31) 1.141 + lfd f4, -(13*8)(r31) 1.142 + lfd f5, -(12*8)(r31) 1.143 + lfd f6, -(11*8)(r31) 1.144 + lfd f7, -(10*8)(r31) 1.145 + lfd f8, -(9*8)(r31) 1.146 + lfd f9, -(8*8)(r31) 1.147 + lfd f10, -(7*8)(r31) 1.148 + lfd f11, -(6*8)(r31) 1.149 + lfd f12, -(5*8)(r31) 1.150 + lfd f13, -(4*8)(r31) 1.151 + 1.152 + bctrl # Do it 1.153 + 1.154 + ld r2,STACK_TOC(r1) # Load our own TOC pointer 1.155 + ld r1,0(r1) # Revert stack frame 1.156 + ld 0,16(r1) # Reload lr 1.157 + ld 29,-24(r1) # Restore NVGPRS 1.158 + ld 30,-16(r1) 1.159 + ld 31,-8(r1) 1.160 + mtlr 0 1.161 + blr 1.162 + 1.163 +#if _CALL_ELF == 2 1.164 + .size NS_InvokeByIndex,.-NS_InvokeByIndex 1.165 +#else 1.166 + .size NS_InvokeByIndex,.-.NS_InvokeByIndex 1.167 +#endif 1.168 + 1.169 + # Magic indicating no need for an executable stack 1.170 + .section .note.GNU-stack, "", @progbits ; .previous