--- /dev/null Mon May 26 13:22:00 2003 +++ xpcom/reflect/xptcall/src/md/unix/xptcstubs_sparc64_freebsd.cpp Mon May 26 04:12:55 2003 @@ -0,0 +1,123 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 2001 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Stuart Parmenter + */ + +/* Implement shared vtbl methods. */ + +#include "xptcprivate.h" + +#if defined(sparc) || defined(__sparc__) + +extern "C" nsresult +PrepareAndDispatch(nsXPTCStubBase* self, PRUint64 methodIndex, PRUint64* args) +{ + +#define PARAM_BUFFER_COUNT 16 + + nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT]; + nsXPTCMiniVariant* dispatchParams = NULL; + nsIInterfaceInfo* iface_info = NULL; + const nsXPTMethodInfo* info; + PRUint8 paramCount; + PRUint8 i; + nsresult result = NS_ERROR_FAILURE; + + NS_ASSERTION(self,"no self"); + + self->GetInterfaceInfo(&iface_info); + NS_ASSERTION(iface_info,"no interface info"); + + iface_info->GetMethodInfo(PRUint16(methodIndex), &info); + NS_ASSERTION(info,"no interface info"); + + paramCount = info->GetParamCount(); + + // setup variant array pointer + if(paramCount > PARAM_BUFFER_COUNT) + dispatchParams = new nsXPTCMiniVariant[paramCount]; + else + dispatchParams = paramBuffer; + NS_ASSERTION(dispatchParams,"no place for params"); + + PRUint64* ap = args; + for(i = 0; i < paramCount; i++, ap++) + { + const nsXPTParamInfo& param = info->GetParam(i); + const nsXPTType& type = param.GetType(); + nsXPTCMiniVariant* dp = &dispatchParams[i]; + + if(param.IsOut() || !type.IsArithmetic()) + { + dp->val.p = (void*) *ap; + continue; + } + // else + switch(type) + { + case nsXPTType::T_I8 : dp->val.i8 = *((PRInt64*) ap); break; + case nsXPTType::T_I16 : dp->val.i16 = *((PRInt64*) ap); break; + case nsXPTType::T_I32 : dp->val.i32 = *((PRInt64*) ap); break; + case nsXPTType::T_DOUBLE : dp->val.d = *((double*) ap); break; + case nsXPTType::T_U64 : dp->val.u64 = *((PRUint64*) ap); break; + case nsXPTType::T_I64 : dp->val.i64 = *((PRInt64*) ap); break; + case nsXPTType::T_U8 : dp->val.u8 = *((PRUint64*) ap); break; + case nsXPTType::T_U16 : dp->val.u16 = *((PRUint64*)ap); break; + case nsXPTType::T_U32 : dp->val.u32 = *((PRUint64*)ap); break; + case nsXPTType::T_FLOAT : dp->val.f = ((float*) ap)[1]; break; + case nsXPTType::T_BOOL : dp->val.b = *((PRInt64*) ap); break; + case nsXPTType::T_CHAR : dp->val.c = *((PRUint64*) ap); break; + case nsXPTType::T_WCHAR : dp->val.wc = *((PRInt64*) ap); break; + default: + NS_ASSERTION(0, "bad type"); + break; + } + } + + result = self->CallMethod((PRUint16)methodIndex, info, dispatchParams); + + NS_RELEASE(iface_info); + + if(dispatchParams != paramBuffer) + delete [] dispatchParams; + + return result; +} + +extern "C" int SharedStub(int, int*); + +#define STUB_ENTRY(n) \ +nsresult nsXPTCStubBase::Stub##n() \ +{ \ + int dummy; /* defeat tail-call optimization */ \ + return SharedStub(n, &dummy); \ +} + +#define SENTINEL_ENTRY(n) \ +nsresult nsXPTCStubBase::Sentinel##n() \ +{ \ + NS_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \ + return NS_ERROR_NOT_IMPLEMENTED; \ +} + +#include "xptcstubsdef.inc" + +#endif /* sparc || __sparc__ */ --- /dev/null Mon May 26 13:22:00 2003 +++ xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparc64_freebsd.s Mon May 26 04:06:09 2003 @@ -0,0 +1,104 @@ +/* -*- Mode: asm; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 2001 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Stuart Parmenter + * Chris Seawood + */ + +/* + Platform specific code to invoke XPCOM methods on native objects + for sparcv9 Solaris. + + See the SPARC Compliance Definition (SCD) Chapter 3 + for more information about what is going on here, including + the use of BIAS (0x7ff). + The SCD is available from http://www.sparc.com/. +*/ + + .global XPTC_InvokeByIndex + .type XPTC_InvokeByIndex, #function + +/* + XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, + PRUint32 paramCount, nsXPTCVariant* params); + +*/ +XPTC_InvokeByIndex: + save %sp,-(128 + 64),%sp ! room for the register window and + ! struct pointer, rounded up to 0 % 64 + sll %i2,4,%l0 ! assume the worst case + ! paramCount * 2 * 8 bytes + cmp %l0, 0 ! are there any args? If not, + be .invoke ! no need to copy args to stack + nop + + sub %sp,%l0,%sp ! create the additional stack space + add %sp,0x7ff+136,%o0 ! step past the register window, the + ! struct result pointer and the 'this' slot + mov %i2,%o1 ! paramCount + call invoke_copy_to_stack + mov %i3,%o2 ! params + +! +! load arguments from stack into the outgoing registers +! BIAS is 0x7ff (2047) +! + +! load the %o1..5 64bit (extended word) output registers registers + ldx [%sp + 0x7ff + 136],%o1 ! %i1 + ldx [%sp + 0x7ff + 144],%o2 ! %i2 + ldx [%sp + 0x7ff + 152],%o3 ! %i3 + ldx [%sp + 0x7ff + 160],%o4 ! %i4 + ldx [%sp + 0x7ff + 168],%o5 ! %i5 + +! load the even number double registers starting with %d2 + ldd [%sp + 0x7ff + 136],%f2 + ldd [%sp + 0x7ff + 144],%f4 + ldd [%sp + 0x7ff + 152],%f6 + ldd [%sp + 0x7ff + 160],%f8 + ldd [%sp + 0x7ff + 168],%f10 + ldd [%sp + 0x7ff + 176],%f12 + ldd [%sp + 0x7ff + 184],%f14 + ldd [%sp + 0x7ff + 192],%f16 + ldd [%sp + 0x7ff + 200],%f18 + ldd [%sp + 0x7ff + 208],%f20 + ldd [%sp + 0x7ff + 216],%f22 + ldd [%sp + 0x7ff + 224],%f24 + ldd [%sp + 0x7ff + 232],%f26 + ldd [%sp + 0x7ff + 240],%f28 + ldd [%sp + 0x7ff + 248],%f30 + +! +! calculate the target address from the vtable +! +.invoke: + sll %i1,3,%l0 ! index *= 8 +! add %l0,16,%l0 ! there are 2 extra entries in the vTable (16bytes) + ldx [%i0],%l1 ! *that --> address of vtable + ldx [%l0 + %l1],%l0 ! that->vtable[index * 8 + 16] --> address + + jmpl %l0,%o7 ! call the routine + mov %i0,%o0 ! move 'this' pointer to out register + + mov %o0,%i0 ! propagate return value + ret + restore + + .size XPTC_InvokeByIndex, .-XPTC_InvokeByIndex --- /dev/null Mon May 26 14:00:00 2003 +++ xpcom/reflect/xptcall/src/md/unix/xptcinvoke_sparc64_freebsd.cpp Mon May 26 14:00:49 2003 @@ -0,0 +1,91 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 2001 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Stuart Parmenter + * Chris Seawood + */ + + +/* Platform specific code to invoke XPCOM methods on native objects */ + +#include "xptcprivate.h" + +#if !defined(__sparc) && !defined(__sparc__) +#error "This code is for Sparc only" +#endif + +/* Prototype specifies unmangled function name */ +extern "C" PRUint64 +invoke_copy_to_stack(PRUint64* d, PRUint32 paramCount, nsXPTCVariant* s); + +extern "C" PRUint64 +invoke_copy_to_stack(PRUint64* d, PRUint32 paramCount, nsXPTCVariant* s) +{ + /* + We need to copy the parameters for this function to locals and use them + from there since the parameters occupy the same stack space as the stack + we're trying to populate. + */ + PRUint64 *l_d = d; + nsXPTCVariant *l_s = s; + PRUint64 l_paramCount = paramCount; + PRUint64 regCount = 0; // return the number of registers to load from the stack + + for(PRUint64 i = 0; i < l_paramCount; i++, l_d++, l_s++) + { + if (regCount < 5) regCount++; + + if (l_s->IsPtrData()) + { + *l_d = (PRUint64)l_s->ptr; + continue; + } + switch (l_s->type) + { + case nsXPTType::T_I8 : *((PRInt64*)l_d) = l_s->val.i8; break; + case nsXPTType::T_I16 : *((PRInt64*)l_d) = l_s->val.i16; break; + case nsXPTType::T_I32 : *((PRInt64*)l_d) = l_s->val.i32; break; + case nsXPTType::T_I64 : *((PRInt64*)l_d) = l_s->val.i64; break; + + case nsXPTType::T_U8 : *((PRUint64*)l_d) = l_s->val.u8; break; + case nsXPTType::T_U16 : *((PRUint64*)l_d) = l_s->val.u16; break; + case nsXPTType::T_U32 : *((PRUint64*)l_d) = l_s->val.u32; break; + case nsXPTType::T_U64 : *((PRUint64*)l_d) = l_s->val.u64; break; + + /* in the case of floats, we want to put the bits in to the + 64bit space right justified... floats in the paramter array on + sparcv9 use odd numbered registers.. %f1, %f3, so we have to skip + the space that would be occupied by %f0, %f2, etc. + */ + case nsXPTType::T_FLOAT : *(((float*)l_d) + 1) = l_s->val.f; break; + case nsXPTType::T_DOUBLE: *((double*)l_d) = l_s->val.d; break; + case nsXPTType::T_BOOL : *((PRInt64*)l_d) = l_s->val.b; break; + case nsXPTType::T_CHAR : *((PRUint64*)l_d) = l_s->val.c; break; + case nsXPTType::T_WCHAR : *((PRInt64*)l_d) = l_s->val.wc; break; + + default: + // all the others are plain pointer types + *((void**)l_d) = l_s->val.p; + break; + } + } + + return regCount; +}