Part of bug #90010. Mozilla on linux/s390(x). r=wtc,sr=shaver,a=dbaron(ports)

This commit is contained in:
blizzard%redhat.com 2003-01-27 21:52:52 +00:00
parent 236f14df17
commit fba7fcc785
5 changed files with 899 additions and 0 deletions

View File

@ -315,6 +315,21 @@ endif
endif
endif
######################################################################
# S/390
######################################################################
#
# Linux for S/390
#
ifeq ($(OS_ARCH)$(OS_TEST),Linuxs390)
CPPSRCS := xptcinvoke_linux_s390.cpp xptcstubs_linux_s390.cpp
endif
ifeq ($(OS_ARCH)$(OS_TEST),Linuxs390x)
CPPSRCS := xptcinvoke_linux_s390x.cpp xptcstubs_linux_s390x.cpp
endif
# we don't want the shared lib, but we want to force the creation of a static lib.
FORCE_STATIC_LIB = 1

View File

@ -0,0 +1,238 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
/* Platform specific code to invoke XPCOM methods on native objects */
#include "xptcprivate.h"
static PRUint32
invoke_count_words(PRUint32 paramCount, nsXPTCVariant* s)
{
PRUint32 overflow = 0, gpr = 1 /*this*/, fpr = 0;
for(PRUint32 i = 0; i < paramCount; i++, s++)
{
if(s->IsPtrData())
{
if (gpr < 5) gpr++; else overflow++;
continue;
}
switch(s->type)
{
case nsXPTType::T_I8 :
case nsXPTType::T_I16 :
case nsXPTType::T_I32 :
if (gpr < 5) gpr++; else overflow++;
break;
case nsXPTType::T_I64 :
if (gpr < 4) gpr+=2; else gpr=5, overflow+=2;
break;
case nsXPTType::T_U8 :
case nsXPTType::T_U16 :
case nsXPTType::T_U32 :
if (gpr < 5) gpr++; else overflow++;
break;
case nsXPTType::T_U64 :
if (gpr < 4) gpr+=2; else gpr=5, overflow+=2;
break;
case nsXPTType::T_FLOAT :
if (fpr < 2) fpr++; else overflow++;
break;
case nsXPTType::T_DOUBLE :
if (fpr < 2) fpr++; else overflow+=2;
break;
case nsXPTType::T_BOOL :
case nsXPTType::T_CHAR :
case nsXPTType::T_WCHAR :
if (gpr < 5) gpr++; else overflow++;
break;
default:
// all the others are plain pointer types
if (gpr < 5) gpr++; else overflow++;
break;
}
}
/* Round up number of overflow words to ensure stack
stays aligned to 8 bytes. */
return (overflow + 1) & ~1;
}
static void
invoke_copy_to_stack(PRUint32 paramCount, nsXPTCVariant* s, PRUint32* d_ov, PRUint32 overflow)
{
PRUint32 *d_gpr = d_ov + overflow;
PRUint64 *d_fpr = (PRUint64 *)(d_gpr + 4);
PRUint32 gpr = 1 /*this*/, fpr = 0;
for(PRUint32 i = 0; i < paramCount; i++, s++)
{
if(s->IsPtrData())
{
if (gpr < 5)
*((void**)d_gpr) = s->ptr, d_gpr++, gpr++;
else
*((void**)d_ov ) = s->ptr, d_ov++;
continue;
}
switch(s->type)
{
case nsXPTType::T_I8 :
if (gpr < 5)
*((PRInt32*) d_gpr) = s->val.i8, d_gpr++, gpr++;
else
*((PRInt32*) d_ov ) = s->val.i8, d_ov++;
break;
case nsXPTType::T_I16 :
if (gpr < 5)
*((PRInt32*) d_gpr) = s->val.i16, d_gpr++, gpr++;
else
*((PRInt32*) d_ov ) = s->val.i16, d_ov++;
break;
case nsXPTType::T_I32 :
if (gpr < 5)
*((PRInt32*) d_gpr) = s->val.i32, d_gpr++, gpr++;
else
*((PRInt32*) d_ov ) = s->val.i32, d_ov++;
break;
case nsXPTType::T_I64 :
if (gpr < 4)
*((PRInt64*) d_gpr) = s->val.i64, d_gpr+=2, gpr+=2;
else
*((PRInt64*) d_ov ) = s->val.i64, d_ov+=2, gpr=5;
break;
case nsXPTType::T_U8 :
if (gpr < 5)
*((PRUint32*) d_gpr) = s->val.u8, d_gpr++, gpr++;
else
*((PRUint32*) d_ov ) = s->val.u8, d_ov++;
break;
case nsXPTType::T_U16 :
if (gpr < 5)
*((PRUint32*)d_gpr) = s->val.u16, d_gpr++, gpr++;
else
*((PRUint32*)d_ov ) = s->val.u16, d_ov++;
break;
case nsXPTType::T_U32 :
if (gpr < 5)
*((PRUint32*)d_gpr) = s->val.u32, d_gpr++, gpr++;
else
*((PRUint32*)d_ov ) = s->val.u32, d_ov++;
break;
case nsXPTType::T_U64 :
if (gpr < 4)
*((PRUint64*)d_gpr) = s->val.u64, d_gpr+=2, gpr+=2;
else
*((PRUint64*)d_ov ) = s->val.u64, d_ov+=2, gpr=5;
break;
case nsXPTType::T_FLOAT :
if (fpr < 2)
*((float*) d_fpr) = s->val.f, d_fpr++, fpr++;
else
*((float*) d_ov ) = s->val.f, d_ov++;
break;
case nsXPTType::T_DOUBLE :
if (fpr < 2)
*((double*) d_fpr) = s->val.d, d_fpr++, fpr++;
else
*((double*) d_ov ) = s->val.d, d_ov+=2;
break;
case nsXPTType::T_BOOL :
if (gpr < 5)
*((PRUint32*)d_gpr) = s->val.b, d_gpr++, gpr++;
else
*((PRUint32*)d_ov ) = s->val.b, d_ov++;
break;
case nsXPTType::T_CHAR :
if (gpr < 5)
*((PRUint32*)d_gpr) = s->val.c, d_gpr++, gpr++;
else
*((PRUint32*)d_ov ) = s->val.c, d_ov++;
break;
case nsXPTType::T_WCHAR :
if (gpr < 5)
*((PRUint32*)d_gpr) = s->val.wc, d_gpr++, gpr++;
else
*((PRUint32*)d_ov ) = s->val.wc, d_ov++;
break;
default:
// all the others are plain pointer types
if (gpr < 5)
*((void**) d_gpr) = s->val.p, d_gpr++, gpr++;
else
*((void**) d_ov ) = s->val.p, d_ov++;
break;
}
}
}
XPTC_PUBLIC_API(nsresult)
XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex,
PRUint32 paramCount, nsXPTCVariant* params)
{
PRUint32 *vtable = *(PRUint32 **)that;
#if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100 /* G++ V3 ABI */
PRUint32 method = vtable[methodIndex];
#else /* not G++ V3 ABI */
PRUint32 method = vtable[methodIndex + 2];
#endif /* G++ V3 ABI */
PRUint32 overflow = invoke_count_words (paramCount, params);
PRUint32 result;
__asm__ __volatile__
(
"lr 7,15\n\t"
"ahi 7,-32\n\t"
"lr 3,%3\n\t"
"sll 3,2\n\t"
"lcr 3,3\n\t"
"l 2,0(15)\n\t"
"la 15,0(3,7)\n\t"
"st 2,0(15)\n\t"
"lr 2,%1\n\t"
"lr 3,%2\n\t"
"la 4,96(15)\n\t"
"lr 5,%3\n\t"
"basr 14,%4\n\t"
"lr 2,%5\n\t"
"ld 0,112(7)\n\t"
"ld 2,120(7)\n\t"
"lm 3,6,96(7)\n\t"
"basr 14,%6\n\t"
"la 15,32(7)\n\t"
"lr %0,2\n\t"
: "=r" (result)
: "r" (paramCount),
"r" (params),
"r" (overflow),
"a" (invoke_copy_to_stack),
"a" (that),
"a" (method)
: "2", "3", "4", "5", "6", "7", "memory"
);
return result;
}

View File

@ -0,0 +1,234 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
/* Platform specific code to invoke XPCOM methods on native objects */
#include "xptcprivate.h"
static PRUint32
invoke_count_words(PRUint32 paramCount, nsXPTCVariant* s)
{
PRUint32 overflow = 0, gpr = 1 /*this*/, fpr = 0;
for(PRUint32 i = 0; i < paramCount; i++, s++)
{
if(s->IsPtrData())
{
if (gpr < 5) gpr++; else overflow++;
continue;
}
switch(s->type)
{
case nsXPTType::T_I8 :
case nsXPTType::T_I16 :
case nsXPTType::T_I32 :
case nsXPTType::T_I64 :
if (gpr < 5) gpr++; else overflow++;
break;
case nsXPTType::T_U8 :
case nsXPTType::T_U16 :
case nsXPTType::T_U32 :
case nsXPTType::T_U64 :
if (gpr < 5) gpr++; else overflow++;
break;
case nsXPTType::T_FLOAT :
case nsXPTType::T_DOUBLE :
if (fpr < 4) fpr++; else overflow++;
break;
case nsXPTType::T_BOOL :
case nsXPTType::T_CHAR :
case nsXPTType::T_WCHAR :
if (gpr < 5) gpr++; else overflow++;
break;
default:
// all the others are plain pointer types
if (gpr < 5) gpr++; else overflow++;
break;
}
}
/* Round up number of overflow words to ensure stack
stays aligned to 8 bytes. */
return (overflow + 1) & ~1;
}
static void
invoke_copy_to_stack(PRUint32 paramCount, nsXPTCVariant* s, PRUint64* d_ov, PRUint32 overflow)
{
PRUint64 *d_gpr = d_ov + overflow;
PRUint64 *d_fpr = (PRUint64 *)(d_gpr + 4);
PRUint32 gpr = 1 /*this*/, fpr = 0;
for(PRUint32 i = 0; i < paramCount; i++, s++)
{
if(s->IsPtrData())
{
if (gpr < 5)
*((void**)d_gpr) = s->ptr, d_gpr++, gpr++;
else
*((void**)d_ov ) = s->ptr, d_ov++;
continue;
}
switch(s->type)
{
case nsXPTType::T_I8 :
if (gpr < 5)
*((PRInt64*) d_gpr) = s->val.i8, d_gpr++, gpr++;
else
*((PRInt64*) d_ov ) = s->val.i8, d_ov++;
break;
case nsXPTType::T_I16 :
if (gpr < 5)
*((PRInt64*) d_gpr) = s->val.i16, d_gpr++, gpr++;
else
*((PRInt64*) d_ov ) = s->val.i16, d_ov++;
break;
case nsXPTType::T_I32 :
if (gpr < 5)
*((PRInt64*) d_gpr) = s->val.i32, d_gpr++, gpr++;
else
*((PRInt64*) d_ov ) = s->val.i32, d_ov++;
break;
case nsXPTType::T_I64 :
if (gpr < 5)
*((PRInt64*) d_gpr) = s->val.i64, d_gpr++, gpr++;
else
*((PRInt64*) d_ov ) = s->val.i64, d_ov++;
break;
case nsXPTType::T_U8 :
if (gpr < 5)
*((PRUint64*) d_gpr) = s->val.u8, d_gpr++, gpr++;
else
*((PRUint64*) d_ov ) = s->val.u8, d_ov++;
break;
case nsXPTType::T_U16 :
if (gpr < 5)
*((PRUint64*)d_gpr) = s->val.u16, d_gpr++, gpr++;
else
*((PRUint64*)d_ov ) = s->val.u16, d_ov++;
break;
case nsXPTType::T_U32 :
if (gpr < 5)
*((PRUint64*)d_gpr) = s->val.u32, d_gpr++, gpr++;
else
*((PRUint64*)d_ov ) = s->val.u32, d_ov++;
break;
case nsXPTType::T_U64 :
if (gpr < 5)
*((PRUint64*)d_gpr) = s->val.u64, d_gpr++, gpr++;
else
*((PRUint64*)d_ov ) = s->val.u64, d_ov++;
break;
case nsXPTType::T_FLOAT :
if (fpr < 4)
*((float*) d_fpr) = s->val.f, d_fpr++, fpr++;
else
*(((float*) d_ov )+1) = s->val.f, d_ov++;
break;
case nsXPTType::T_DOUBLE :
if (fpr < 4)
*((double*) d_fpr) = s->val.d, d_fpr++, fpr++;
else
*((double*) d_ov ) = s->val.d, d_ov++;
break;
case nsXPTType::T_BOOL :
if (gpr < 5)
*((PRUint64*)d_gpr) = s->val.b, d_gpr++, gpr++;
else
*((PRUint64*)d_ov ) = s->val.b, d_ov++;
break;
case nsXPTType::T_CHAR :
if (gpr < 5)
*((PRUint64*)d_gpr) = s->val.c, d_gpr++, gpr++;
else
*((PRUint64*)d_ov ) = s->val.c, d_ov++;
break;
case nsXPTType::T_WCHAR :
if (gpr < 5)
*((PRUint64*)d_gpr) = s->val.wc, d_gpr++, gpr++;
else
*((PRUint64*)d_ov ) = s->val.wc, d_ov++;
break;
default:
// all the others are plain pointer types
if (gpr < 5)
*((void**) d_gpr) = s->val.p, d_gpr++, gpr++;
else
*((void**) d_ov ) = s->val.p, d_ov++;
break;
}
}
}
XPTC_PUBLIC_API(nsresult)
XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex,
PRUint32 paramCount, nsXPTCVariant* params)
{
PRUint64 *vtable = *(PRUint64 **)that;
#if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100 /* G++ V3 ABI */
PRUint64 method = vtable[methodIndex];
#else /* not G++ V3 ABI */
PRUint64 method = vtable[methodIndex + 2];
#endif /* G++ V3 ABI */
PRUint64 overflow = invoke_count_words (paramCount, params);
PRUint64 result;
__asm__ __volatile__
(
"lgr 7,15\n\t"
"aghi 7,-64\n\t"
"lgr 3,%3\n\t"
"sllg 3,3,3\n\t"
"lcgr 3,3\n\t"
"lg 2,0(15)\n\t"
"la 15,0(3,7)\n\t"
"stg 2,0(15)\n\t"
"lgr 2,%1\n\t"
"lgr 3,%2\n\t"
"la 4,160(15)\n\t"
"lgr 5,%3\n\t"
"basr 14,%4\n\t"
"lgr 2,%5\n\t"
"ld 0,192(7)\n\t"
"ld 2,200(7)\n\t"
"ld 4,208(7)\n\t"
"ld 6,216(7)\n\t"
"lmg 3,6,160(7)\n\t"
"basr 14,%6\n\t"
"la 15,64(7)\n\t"
"lgr %0,2\n\t"
: "=r" (result)
: "r" ((PRUint64)paramCount),
"r" (params),
"r" (overflow),
"a" (invoke_copy_to_stack),
"a" (that),
"a" (method)
: "2", "3", "4", "5", "6", "7", "memory"
);
return result;
}

View File

@ -0,0 +1,204 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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) 1999 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
/* Implement shared vtbl methods. */
#include "xptcprivate.h"
static nsresult
PrepareAndDispatch(nsXPTCStubBase* self, uint32 methodIndex,
PRUint32* a_gpr, PRUint64 *a_fpr, PRUint32 *a_ov)
{
#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");
PRUint32 gpr = 1, fpr = 0;
for(i = 0; i < paramCount; i++)
{
const nsXPTParamInfo& param = info->GetParam(i);
const nsXPTType& type = param.GetType();
nsXPTCMiniVariant* dp = &dispatchParams[i];
if(param.IsOut() || !type.IsArithmetic())
{
if (gpr < 5)
dp->val.p = (void*) *a_gpr++, gpr++;
else
dp->val.p = (void*) *a_ov++;
continue;
}
// else
switch(type)
{
case nsXPTType::T_I8 :
if (gpr < 5)
dp->val.i8 = *((PRInt32*) a_gpr), a_gpr++, gpr++;
else
dp->val.i8 = *((PRInt32*) a_ov ), a_ov++;
break;
case nsXPTType::T_I16 :
if (gpr < 5)
dp->val.i16 = *((PRInt32*) a_gpr), a_gpr++, gpr++;
else
dp->val.i16 = *((PRInt32*) a_ov ), a_ov++;
break;
case nsXPTType::T_I32 :
if (gpr < 5)
dp->val.i32 = *((PRInt32*) a_gpr), a_gpr++, gpr++;
else
dp->val.i32 = *((PRInt32*) a_ov ), a_ov++;
break;
case nsXPTType::T_I64 :
if (gpr < 4)
dp->val.i64 = *((PRInt64*) a_gpr), a_gpr+=2, gpr+=2;
else
dp->val.i64 = *((PRInt64*) a_ov ), a_ov+=2, gpr=5;
break;
case nsXPTType::T_U8 :
if (gpr < 5)
dp->val.u8 = *((PRUint32*)a_gpr), a_gpr++, gpr++;
else
dp->val.u8 = *((PRUint32*)a_ov ), a_ov++;
break;
case nsXPTType::T_U16 :
if (gpr < 5)
dp->val.u16 = *((PRUint32*)a_gpr), a_gpr++, gpr++;
else
dp->val.u16 = *((PRUint32*)a_ov ), a_ov++;
break;
case nsXPTType::T_U32 :
if (gpr < 5)
dp->val.u32 = *((PRUint32*)a_gpr), a_gpr++, gpr++;
else
dp->val.u32 = *((PRUint32*)a_ov ), a_ov++;
break;
case nsXPTType::T_U64 :
if (gpr < 4)
dp->val.u64 = *((PRUint64*)a_gpr), a_gpr+=2, gpr+=2;
else
dp->val.u64 = *((PRUint64*)a_ov ), a_ov+=2, gpr=5;
break;
case nsXPTType::T_FLOAT :
if (fpr < 2)
dp->val.f = *((float*) a_fpr), a_fpr++, fpr++;
else
dp->val.f = *((float*) a_ov ), a_ov++;
break;
case nsXPTType::T_DOUBLE :
if (fpr < 2)
dp->val.d = *((double*) a_fpr), a_fpr++, fpr++;
else
dp->val.d = *((double*) a_ov ), a_ov+=2;
break;
case nsXPTType::T_BOOL :
if (gpr < 5)
dp->val.b = *((PRUint32*)a_gpr), a_gpr++, gpr++;
else
dp->val.b = *((PRUint32*)a_ov ), a_ov++;
break;
case nsXPTType::T_CHAR :
if (gpr < 5)
dp->val.c = *((PRUint32*)a_gpr), a_gpr++, gpr++;
else
dp->val.c = *((PRUint32*)a_ov ), a_ov++;
break;
case nsXPTType::T_WCHAR :
if (gpr < 5)
dp->val.wc = *((PRUint32*)a_gpr), a_gpr++, gpr++;
else
dp->val.wc = *((PRUint32*)a_ov ), a_ov++;
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;
}
#define STUB_ENTRY(n) \
nsresult nsXPTCStubBase::Stub##n() \
{ \
PRUint32 a_gpr[4]; \
PRUint64 a_fpr[2]; \
PRUint32 *a_ov; \
\
__asm__ __volatile__ \
( \
"l %0,0(15)\n\t" \
"ahi %0,96\n\t" \
"stm 3,6,0(%3)\n\t" \
"std 0,%1\n\t" \
"std 2,%2\n\t" \
: "=&a" (a_ov), \
"=m" (a_fpr[0]), \
"=m" (a_fpr[1]) \
: "a" (a_gpr) \
: "memory", "cc", \
"3", "4", "5", "6" \
); \
\
return PrepareAndDispatch(this, n, a_gpr, a_fpr, a_ov); \
}
#define SENTINEL_ENTRY(n) \
nsresult nsXPTCStubBase::Sentinel##n() \
{ \
NS_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \
return NS_ERROR_NOT_IMPLEMENTED; \
}
#include "xptcstubsdef.inc"

View File

@ -0,0 +1,208 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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) 1999 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
/* Implement shared vtbl methods. */
#include "xptcprivate.h"
static nsresult
PrepareAndDispatch(nsXPTCStubBase* self, uint32 methodIndex,
PRUint64* a_gpr, PRUint64 *a_fpr, PRUint64 *a_ov)
{
#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");
PRUint32 gpr = 1, fpr = 0;
for(i = 0; i < paramCount; i++)
{
const nsXPTParamInfo& param = info->GetParam(i);
const nsXPTType& type = param.GetType();
nsXPTCMiniVariant* dp = &dispatchParams[i];
if(param.IsOut() || !type.IsArithmetic())
{
if (gpr < 5)
dp->val.p = (void*) *a_gpr++, gpr++;
else
dp->val.p = (void*) *a_ov++;
continue;
}
// else
switch(type)
{
case nsXPTType::T_I8 :
if (gpr < 5)
dp->val.i8 = *((PRInt64*) a_gpr), a_gpr++, gpr++;
else
dp->val.i8 = *((PRInt64*) a_ov ), a_ov++;
break;
case nsXPTType::T_I16 :
if (gpr < 5)
dp->val.i16 = *((PRInt64*) a_gpr), a_gpr++, gpr++;
else
dp->val.i16 = *((PRInt64*) a_ov ), a_ov++;
break;
case nsXPTType::T_I32 :
if (gpr < 5)
dp->val.i32 = *((PRInt64*) a_gpr), a_gpr++, gpr++;
else
dp->val.i32 = *((PRInt64*) a_ov ), a_ov++;
break;
case nsXPTType::T_I64 :
if (gpr < 5)
dp->val.i64 = *((PRInt64*) a_gpr), a_gpr++, gpr++;
else
dp->val.i64 = *((PRInt64*) a_ov ), a_ov++;
break;
case nsXPTType::T_U8 :
if (gpr < 5)
dp->val.u8 = *((PRUint64*)a_gpr), a_gpr++, gpr++;
else
dp->val.u8 = *((PRUint64*)a_ov ), a_ov++;
break;
case nsXPTType::T_U16 :
if (gpr < 5)
dp->val.u16 = *((PRUint64*)a_gpr), a_gpr++, gpr++;
else
dp->val.u16 = *((PRUint64*)a_ov ), a_ov++;
break;
case nsXPTType::T_U32 :
if (gpr < 5)
dp->val.u32 = *((PRUint64*)a_gpr), a_gpr++, gpr++;
else
dp->val.u32 = *((PRUint64*)a_ov ), a_ov++;
break;
case nsXPTType::T_U64 :
if (gpr < 5)
dp->val.u64 = *((PRUint64*)a_gpr), a_gpr++, gpr++;
else
dp->val.u64 = *((PRUint64*)a_ov ), a_ov++;
break;
case nsXPTType::T_FLOAT :
if (fpr < 4)
dp->val.f = *((float*) a_fpr), a_fpr++, fpr++;
else
dp->val.f = *(((float*) a_ov )+1), a_ov++;
break;
case nsXPTType::T_DOUBLE :
if (fpr < 4)
dp->val.d = *((double*) a_fpr), a_fpr++, fpr++;
else
dp->val.d = *((double*) a_ov ), a_ov++;
break;
case nsXPTType::T_BOOL :
if (gpr < 5)
dp->val.b = *((PRUint64*)a_gpr), a_gpr++, gpr++;
else
dp->val.b = *((PRUint64*)a_ov ), a_ov++;
break;
case nsXPTType::T_CHAR :
if (gpr < 5)
dp->val.c = *((PRUint64*)a_gpr), a_gpr++, gpr++;
else
dp->val.c = *((PRUint64*)a_ov ), a_ov++;
break;
case nsXPTType::T_WCHAR :
if (gpr < 5)
dp->val.wc = *((PRUint64*)a_gpr), a_gpr++, gpr++;
else
dp->val.wc = *((PRUint64*)a_ov ), a_ov++;
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;
}
#define STUB_ENTRY(n) \
nsresult nsXPTCStubBase::Stub##n() \
{ \
PRUint64 a_gpr[4]; \
PRUint64 a_fpr[4]; \
PRUint64 *a_ov; \
\
__asm__ __volatile__ \
( \
"lg %0,0(15)\n\t" \
"aghi %0,160\n\t" \
"stmg 3,6,0(%5)\n\t"\
"std 0,%1\n\t" \
"std 2,%2\n\t" \
"std 4,%3\n\t" \
"std 6,%4\n\t" \
: "=&a" (a_ov), \
"=m" (a_fpr[0]), \
"=m" (a_fpr[1]), \
"=m" (a_fpr[2]), \
"=m" (a_fpr[3]) \
: "a" (a_gpr) \
: "memory", "cc", \
"3", "4", "5", "6" \
); \
\
return PrepareAndDispatch(this, n, a_gpr, a_fpr, a_ov); \
}
#define SENTINEL_ENTRY(n) \
nsresult nsXPTCStubBase::Sentinel##n() \
{ \
NS_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \
return NS_ERROR_NOT_IMPLEMENTED; \
}
#include "xptcstubsdef.inc"