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