1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/xpcom/reflect/xptcall/src/md/unix/xptcstubs_linux_alpha.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,187 @@ 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 + 1.9 +/* Implement shared vtbl methods. */ 1.10 + 1.11 +#include "xptcprivate.h" 1.12 +#include "xptiprivate.h" 1.13 + 1.14 +/* Prototype specifies unmangled function name and disables unused warning */ 1.15 +static nsresult 1.16 +PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex, uint64_t* args) 1.17 +__asm__("PrepareAndDispatch") ATTRIBUTE_USED; 1.18 + 1.19 +static nsresult 1.20 +PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex, uint64_t* args) 1.21 +{ 1.22 + const uint8_t PARAM_BUFFER_COUNT = 16; 1.23 + const uint8_t NUM_ARG_REGS = 6-1; // -1 for "this" pointer 1.24 + 1.25 + nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT]; 1.26 + nsXPTCMiniVariant* dispatchParams = nullptr; 1.27 + const nsXPTMethodInfo* info; 1.28 + uint8_t paramCount; 1.29 + uint8_t i; 1.30 + nsresult result = NS_ERROR_FAILURE; 1.31 + 1.32 + NS_ASSERTION(self,"no self"); 1.33 + 1.34 + self->mEntry->GetMethodInfo(uint16_t(methodIndex), &info); 1.35 + 1.36 + paramCount = info->GetParamCount(); 1.37 + 1.38 + // setup variant array pointer 1.39 + if(paramCount > PARAM_BUFFER_COUNT) 1.40 + dispatchParams = new nsXPTCMiniVariant[paramCount]; 1.41 + else 1.42 + dispatchParams = paramBuffer; 1.43 + NS_ASSERTION(dispatchParams,"no place for params"); 1.44 + 1.45 + // args[0] to args[NUM_ARG_REGS] hold floating point register values 1.46 + uint64_t* ap = args + NUM_ARG_REGS; 1.47 + for(i = 0; i < paramCount; i++, ap++) 1.48 + { 1.49 + const nsXPTParamInfo& param = info->GetParam(i); 1.50 + const nsXPTType& type = param.GetType(); 1.51 + nsXPTCMiniVariant* dp = &dispatchParams[i]; 1.52 + 1.53 + if(param.IsOut() || !type.IsArithmetic()) 1.54 + { 1.55 + dp->val.p = (void*) *ap; 1.56 + continue; 1.57 + } 1.58 + // else 1.59 + switch(type) 1.60 + { 1.61 + case nsXPTType::T_I8 : dp->val.i8 = (int8_t) *ap; break; 1.62 + case nsXPTType::T_I16 : dp->val.i16 = (int16_t) *ap; break; 1.63 + case nsXPTType::T_I32 : dp->val.i32 = (int32_t) *ap; break; 1.64 + case nsXPTType::T_I64 : dp->val.i64 = (int64_t) *ap; break; 1.65 + case nsXPTType::T_U8 : dp->val.u8 = (uint8_t) *ap; break; 1.66 + case nsXPTType::T_U16 : dp->val.u16 = (uint16_t) *ap; break; 1.67 + case nsXPTType::T_U32 : dp->val.u32 = (uint32_t) *ap; break; 1.68 + case nsXPTType::T_U64 : dp->val.u64 = (uint64_t) *ap; break; 1.69 + case nsXPTType::T_FLOAT : 1.70 + if(i < NUM_ARG_REGS) 1.71 + { 1.72 + // floats passed via registers are stored as doubles 1.73 + // in the first NUM_ARG_REGS entries in args 1.74 + dp->val.u64 = (uint64_t) args[i]; 1.75 + dp->val.f = (float) dp->val.d; // convert double to float 1.76 + } 1.77 + else 1.78 + dp->val.u32 = (uint32_t) *ap; 1.79 + break; 1.80 + case nsXPTType::T_DOUBLE : 1.81 + // doubles passed via registers are also stored 1.82 + // in the first NUM_ARG_REGS entries in args 1.83 + dp->val.u64 = (i < NUM_ARG_REGS) ? args[i] : *ap; 1.84 + break; 1.85 + case nsXPTType::T_BOOL : dp->val.b = (bool) *ap; break; 1.86 + case nsXPTType::T_CHAR : dp->val.c = (char) *ap; break; 1.87 + case nsXPTType::T_WCHAR : dp->val.wc = (char16_t) *ap; break; 1.88 + default: 1.89 + NS_ERROR("bad type"); 1.90 + break; 1.91 + } 1.92 + } 1.93 + 1.94 + result = self->mOuter->CallMethod((uint16_t)methodIndex, info, dispatchParams); 1.95 + 1.96 + if(dispatchParams != paramBuffer) 1.97 + delete [] dispatchParams; 1.98 + 1.99 + return result; 1.100 +} 1.101 + 1.102 +/* 1.103 + * SharedStub() 1.104 + * Collects arguments and calls PrepareAndDispatch. The "methodIndex" is 1.105 + * passed to this function via $1 to preserve the argument registers. 1.106 + */ 1.107 +__asm__( 1.108 + "#### SharedStub ####\n" 1.109 +".text\n\t" 1.110 + ".align 5\n\t" 1.111 + ".ent SharedStub\n" 1.112 +"SharedStub:\n\t" 1.113 + ".frame $30,96,$26,0\n\t" 1.114 + ".mask 0x4000000,-96\n\t" 1.115 + "ldgp $29,0($27)\n" 1.116 +"$SharedStub..ng:\n\t" 1.117 + "subq $30,96,$30\n\t" 1.118 + "stq $26,0($30)\n\t" 1.119 + ".prologue 1\n\t" 1.120 + 1.121 + /* 1.122 + * Store arguments passed via registers to the stack. 1.123 + * Floating point registers are stored as doubles and converted 1.124 + * to floats in PrepareAndDispatch if necessary. 1.125 + */ 1.126 + "stt $f17,16($30)\n\t" /* floating point registers */ 1.127 + "stt $f18,24($30)\n\t" 1.128 + "stt $f19,32($30)\n\t" 1.129 + "stt $f20,40($30)\n\t" 1.130 + "stt $f21,48($30)\n\t" 1.131 + "stq $17,56($30)\n\t" /* integer registers */ 1.132 + "stq $18,64($30)\n\t" 1.133 + "stq $19,72($30)\n\t" 1.134 + "stq $20,80($30)\n\t" 1.135 + "stq $21,88($30)\n\t" 1.136 + 1.137 + /* 1.138 + * Call PrepareAndDispatch function. 1.139 + */ 1.140 + "bis $1,$1,$17\n\t" /* pass "methodIndex" */ 1.141 + "addq $30,16,$18\n\t" /* pass "args" */ 1.142 + "bsr $26,$PrepareAndDispatch..ng\n\t" 1.143 + 1.144 + "ldq $26,0($30)\n\t" 1.145 + "addq $30,96,$30\n\t" 1.146 + "ret $31,($26),1\n\t" 1.147 + ".end SharedStub" 1.148 + ); 1.149 + 1.150 +/* 1.151 + * nsresult nsXPTCStubBase::Stub##n() 1.152 + * Sets register $1 to "methodIndex" and jumps to SharedStub. 1.153 + */ 1.154 +#define STUB_MANGLED_ENTRY(n, symbol) \ 1.155 + "#### Stub"#n" ####" "\n\t" \ 1.156 + ".text" "\n\t" \ 1.157 + ".align 5" "\n\t" \ 1.158 + ".globl " symbol "\n\t" \ 1.159 + ".ent " symbol "\n" \ 1.160 +symbol ":" "\n\t" \ 1.161 + ".frame $30,0,$26,0" "\n\t" \ 1.162 + "ldgp $29,0($27)" "\n" \ 1.163 +"$" symbol "..ng:" "\n\t" \ 1.164 + ".prologue 1" "\n\t" \ 1.165 + "lda $1,"#n "\n\t" \ 1.166 + "br $31,$SharedStub..ng" "\n\t" \ 1.167 + ".end " symbol 1.168 + 1.169 +#define STUB_ENTRY(n) \ 1.170 +__asm__( \ 1.171 + ".if "#n" < 10" "\n\t" \ 1.172 + STUB_MANGLED_ENTRY(n, "_ZN14nsXPTCStubBase5Stub"#n"Ev") "\n\t" \ 1.173 + ".elseif "#n" < 100" "\n\t" \ 1.174 + STUB_MANGLED_ENTRY(n, "_ZN14nsXPTCStubBase6Stub"#n"Ev") "\n\t" \ 1.175 + ".elseif "#n" < 1000" "\n\t" \ 1.176 + STUB_MANGLED_ENTRY(n, "_ZN14nsXPTCStubBase7Stub"#n"Ev") "\n\t" \ 1.177 + ".else" "\n\t" \ 1.178 + ".err \"Stub"#n" >= 1000 not yet supported.\"" "\n\t" \ 1.179 + ".endif" \ 1.180 + ); 1.181 + 1.182 + 1.183 +#define SENTINEL_ENTRY(n) \ 1.184 +nsresult nsXPTCStubBase::Sentinel##n() \ 1.185 +{ \ 1.186 + NS_ERROR("nsXPTCStubBase::Sentinel called"); \ 1.187 + return NS_ERROR_NOT_IMPLEMENTED; \ 1.188 +} 1.189 + 1.190 +#include "xptcstubsdef.inc"