1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_mips64.S Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,122 @@ 1.4 +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 +#include <sys/regdef.h> 1.9 +#include <sys/asm.h> 1.10 + 1.11 +.text 1.12 +.globl invoke_count_words 1.13 +.globl invoke_copy_to_stack 1.14 + 1.15 +LOCALSZ=7 # a0, a1, a2, a3, s0, ra, gp 1.16 +FRAMESZ=(((NARGSAVE+LOCALSZ)*SZREG)+ALSZ)&ALMASK 1.17 + 1.18 +RAOFF=FRAMESZ-(1*SZREG) 1.19 +A0OFF=FRAMESZ-(2*SZREG) 1.20 +A1OFF=FRAMESZ-(3*SZREG) 1.21 +A2OFF=FRAMESZ-(4*SZREG) 1.22 +A3OFF=FRAMESZ-(5*SZREG) 1.23 +S0OFF=FRAMESZ-(6*SZREG) 1.24 +GPOFF=FRAMESZ-(7*SZREG) 1.25 + 1.26 +# 1.27 +# _NS_InvokeByIndex(that, methodIndex, paramCount, params) 1.28 +# a0 a1 a2 a3 1.29 + 1.30 +NESTED(_NS_InvokeByIndex, FRAMESZ, ra) 1.31 + PTR_SUBU sp, FRAMESZ 1.32 + SETUP_GP64(GPOFF, _NS_InvokeByIndex) 1.33 + 1.34 + REG_S ra, RAOFF(sp) 1.35 + REG_S a0, A0OFF(sp) 1.36 + REG_S a1, A1OFF(sp) 1.37 + REG_S a2, A2OFF(sp) 1.38 + REG_S a3, A3OFF(sp) 1.39 + REG_S s0, S0OFF(sp) 1.40 + 1.41 + # invoke_count_words(paramCount, params) 1.42 + move a0, a2 1.43 + move a1, a3 1.44 + jal invoke_count_words 1.45 + 1.46 + # invoke_copy_to_stack(uint32_t* d, uint32_t paramCount, 1.47 + # nsXPTCVariant* s, uint32_t *reg) 1.48 + 1.49 + REG_L a1, A2OFF(sp) # a1 - paramCount 1.50 + REG_L a2, A3OFF(sp) # a2 - params 1.51 + 1.52 + # save sp before we copy the params to the stack 1.53 + move t0, sp 1.54 + 1.55 + # assume full size of 16 bytes per param to be safe 1.56 + sll v0, 4 # 16 bytes * num params 1.57 + subu sp, sp, v0 # make room 1.58 + move a0, sp # a0 - param stack address 1.59 + 1.60 + # create temporary stack space to write int and fp regs 1.61 + subu sp, 64 # 64 = 8 regs of 8 bytes 1.62 + move a3, sp 1.63 + 1.64 + # save the old sp and save the arg stack 1.65 + subu sp, sp, 16 1.66 + REG_S t0, 0(sp) 1.67 + REG_S a0, 8(sp) 1.68 + 1.69 + # copy the param into the stack areas 1.70 + jal invoke_copy_to_stack 1.71 + 1.72 + REG_L t3, 8(sp) # get previous a0 1.73 + REG_L sp, 0(sp) # get orig sp back 1.74 + 1.75 + REG_L a0, A0OFF(sp) # a0 - that 1.76 + REG_L a1, A1OFF(sp) # a1 - methodIndex 1.77 + 1.78 + # t1 = methodIndex * pow(2, PTRLOG) 1.79 + # (use shift instead of mult) 1.80 + sll t1, a1, PTRLOG 1.81 + 1.82 + # calculate the function we need to jump to, 1.83 + # which must then be saved in t9 1.84 + lw t9, 0(a0) 1.85 + addu t9, t9, t1 1.86 + lw t9, (t9) 1.87 + 1.88 + # get register save area from invoke_copy_to_stack 1.89 + subu t1, t3, 64 1.90 + 1.91 + # a1..a7 and f13..f19 should now be set to what 1.92 + # invoke_copy_to_stack told us. skip a0 and f12 1.93 + # because that's the "this" pointer 1.94 + 1.95 + REG_L a1, 0(t1) 1.96 + REG_L a2, 8(t1) 1.97 + REG_L a3, 16(t1) 1.98 + REG_L a4, 24(t1) 1.99 + REG_L a5, 32(t1) 1.100 + REG_L a6, 40(t1) 1.101 + REG_L a7, 48(t1) 1.102 + 1.103 + l.d $f13, 0(t1) 1.104 + l.d $f14, 8(t1) 1.105 + l.d $f15, 16(t1) 1.106 + l.d $f16, 24(t1) 1.107 + l.d $f17, 32(t1) 1.108 + l.d $f18, 40(t1) 1.109 + l.d $f19, 48(t1) 1.110 + 1.111 + # save away our stack pointer and create 1.112 + # the stack pointer for the function 1.113 + move s0, sp 1.114 + move sp, t3 1.115 + 1.116 + jalr t9 1.117 + 1.118 + move sp, s0 1.119 + 1.120 + RESTORE_GP64 1.121 + REG_L ra, RAOFF(sp) 1.122 + REG_L s0, S0OFF(sp) 1.123 + PTR_ADDU sp, FRAMESZ 1.124 + j ra 1.125 +.end _NS_InvokeByIndex