Patches from Franz.Sirl-kernel@lauterbach.com. Get xptcall limping along on PPC/Linux.
git-svn-id: svn://10.0.0.236/trunk@55394 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
6130dcc35b
commit
509d1e72ed
@ -1,128 +1,93 @@
|
||||
#
|
||||
# -*- 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):
|
||||
#
|
||||
|
||||
.set r0,0; .set sp,1; .set RTOC,2; .set r3,3; .set r4,4
|
||||
.set r5,5; .set r6,6; .set r7,7; .set r8,8; .set r9,9
|
||||
.set r10,10; .set r11,11; .set r12,12; .set r13,13; .set r14,14
|
||||
.set r15,15; .set r16,16; .set r17,17; .set r18,18; .set r19,19
|
||||
.set r20,20; .set r21,21; .set r22,22; .set r23,23; .set r24,24
|
||||
.set r25,25; .set r26,26; .set r27,27; .set r28,28; .set r29,29
|
||||
.set r30,30; .set r31,31
|
||||
.set f0,0; .set f1,1; .set f2,2; .set f3,3; .set f4,4
|
||||
.set f5,5; .set f6,6; .set f7,7; .set f8,8; .set f9,9
|
||||
.set f10,10; .set f11,11; .set f12,12; .set f13,13; .set f14,14
|
||||
.set f15,15; .set f16,16; .set f17,17; .set f18,18; .set f19,19
|
||||
.set f20,20; .set f21,21; .set f22,22; .set f23,23; .set f24,24
|
||||
.set f25,25; .set f26,26; .set f27,27; .set f28,28; .set f29,29
|
||||
.set f30,30; .set f31,31
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# .text section
|
||||
|
||||
.globl XPTC_InvokeByIndex
|
||||
.extern invoke_count_words
|
||||
.extern invoke_copy_to_stack
|
||||
|
||||
#
|
||||
# -*- 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):
|
||||
#
|
||||
|
||||
.section ".text"
|
||||
.align 2
|
||||
.globl XPTC_InvokeByIndex
|
||||
.type XPTC_InvokeByIndex,@function
|
||||
|
||||
#
|
||||
# XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex,
|
||||
# PRUint32 paramCount, nsXPTCVariant* params)
|
||||
# XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex,
|
||||
# PRUint32 paramCount, nsXPTCVariant* params)
|
||||
#
|
||||
|
||||
XPTC_InvokeByIndex:
|
||||
mflr r0
|
||||
stw r31,-4(sp)
|
||||
#
|
||||
# save off the incoming values in the caller's parameter area
|
||||
#
|
||||
stw r3,24(sp) # that
|
||||
stw r4,28(sp) # methodIndex
|
||||
stw r5,32(sp) # paramCount
|
||||
stw r6,36(sp) # params
|
||||
stw r0,8(sp)
|
||||
stwu sp,-136(sp) # = 24 for linkage area, 8 * 13 for fprData area, 8 for saved registers
|
||||
stwu 1,-32(1)
|
||||
mflr 0
|
||||
stw 3,8(1) # that
|
||||
stw 4,12(1) # methodIndex
|
||||
stw 30,16(1)
|
||||
stw 31,20(1)
|
||||
|
||||
# set up for and call 'invoke_count_words' to get new stack size
|
||||
#
|
||||
mr r3,r5
|
||||
mr r4,r6
|
||||
bl invoke_count_words
|
||||
nop
|
||||
stw 0,36(1)
|
||||
mr 31,1
|
||||
|
||||
# prepare args for 'invoke_copy_to_stack' call
|
||||
#
|
||||
lwz r4,168(sp) # paramCount
|
||||
lwz r5,172(sp) # params
|
||||
mr r6,sp # fprData
|
||||
slwi r3,r3,2 # number of bytes of stack required
|
||||
addi r3,r3,28 # linkage area
|
||||
mr r31,sp # save original stack top
|
||||
subfc sp,r3,sp # bump the stack
|
||||
addi r3,sp,28 # parameter pointer excludes linkage area size + 'this'
|
||||
|
||||
bl invoke_copy_to_stack
|
||||
nop
|
||||
|
||||
lfd f1,0(r31) # Restore floating point registers
|
||||
lfd f2,8(r31)
|
||||
lfd f3,16(r31)
|
||||
lfd f4,24(r31)
|
||||
lfd f5,32(r31)
|
||||
lfd f6,40(r31)
|
||||
lfd f7,48(r31)
|
||||
lfd f8,56(r31)
|
||||
lfd f9,64(r31)
|
||||
lfd f10,72(r31)
|
||||
lfd f11,80(r31)
|
||||
lfd f12,88(r31)
|
||||
lfd f13,96(r31)
|
||||
|
||||
lwz r3,160(r31) # that
|
||||
lwz r4,0(r3) # get vTable from 'that'
|
||||
lwz r5,164(r31) # methodIndex
|
||||
slwi r5,r5,3 # methodIndex * 8
|
||||
addi r5,r5,8 # step over junk at start of vTable !
|
||||
lwzx r11,r5,r4 # get function pointer
|
||||
|
||||
lwz r4,28(sp)
|
||||
lwz r5,32(sp)
|
||||
lwz r6,36(sp)
|
||||
lwz r7,40(sp)
|
||||
lwz r8,44(sp)
|
||||
lwz r9,48(sp)
|
||||
lwz r10,52(sp)
|
||||
slwi 10,5,3 # reserve stack for ParamCount *2 *4
|
||||
addi 0,10,128 # reserve stack for GPR and FPR
|
||||
lwz 9,0(1)
|
||||
neg 0,0
|
||||
stwux 9,1,0
|
||||
addi 3,1,8 # args
|
||||
mr 4,5 # paramCount
|
||||
mr 5,6 # params
|
||||
add 6,3,10 # gpregs
|
||||
mr 30,6
|
||||
addi 7,6,32 # fpregs
|
||||
|
||||
mtlr r11
|
||||
blrl
|
||||
|
||||
mr sp,r31
|
||||
lwz r0,144(sp)
|
||||
addi sp,sp,136
|
||||
mtlr r0
|
||||
lwz r31,-4(sp)
|
||||
blr
|
||||
bl invoke_copy_to_stack # (args, paramCount, params, gpregs, fpregs)
|
||||
|
||||
lfd 1,32(30) # load FP registers
|
||||
lfd 2,40(30)
|
||||
lfd 3,48(30)
|
||||
lfd 4,56(30)
|
||||
lfd 5,64(30)
|
||||
lfd 6,72(30)
|
||||
lfd 7,80(30)
|
||||
lfd 8,88(30)
|
||||
|
||||
lwz 3,8(31) # that
|
||||
lwz 4,12(31) # methodIndex
|
||||
|
||||
lwz 5,0(3) # vtable
|
||||
slwi 4,4,2 # temp = methodIndex * 4
|
||||
addi 4,4,8 # temp += 8
|
||||
lwzx 0,4,5 # dest = vtable+temp
|
||||
|
||||
lwz 4,0(30) # load GP regs
|
||||
lwz 5,4(30)
|
||||
lwz 6,8(30)
|
||||
lwz 7,12(30)
|
||||
lwz 8,16(30)
|
||||
lwz 9,20(30)
|
||||
lwz 10,24(30)
|
||||
|
||||
mtlr 0
|
||||
blrl # call
|
||||
|
||||
lwz 30,16(31) # clean up stack
|
||||
lwz 31,20(31)
|
||||
lwz 11,0(1)
|
||||
lwz 0,4(11)
|
||||
mtlr 0
|
||||
mr 1,11
|
||||
blr
|
||||
|
||||
@ -26,106 +26,190 @@
|
||||
|
||||
typedef unsigned nsXPCVariant;
|
||||
|
||||
#define FIRST_GP_REG 3
|
||||
#define MAX_GP_REG 10
|
||||
#define FIRST_FP_REG 1
|
||||
#define MAX_FP_REG 8
|
||||
|
||||
extern "C" PRUint32
|
||||
invoke_count_words(PRUint32 paramCount, nsXPTCVariant* s)
|
||||
{
|
||||
PRUint32 result = 0;
|
||||
for(PRUint32 i = 0; i < paramCount; i++, s++)
|
||||
{
|
||||
if(s->IsPtrData())
|
||||
{
|
||||
result++;
|
||||
continue;
|
||||
}
|
||||
switch(s->type)
|
||||
{
|
||||
case nsXPTType::T_I8 :
|
||||
case nsXPTType::T_I16 :
|
||||
case nsXPTType::T_I32 :
|
||||
result++;
|
||||
break;
|
||||
case nsXPTType::T_I64 :
|
||||
result+=2;
|
||||
break;
|
||||
case nsXPTType::T_U8 :
|
||||
case nsXPTType::T_U16 :
|
||||
case nsXPTType::T_U32 :
|
||||
result++;
|
||||
break;
|
||||
case nsXPTType::T_U64 :
|
||||
result+=2;
|
||||
break;
|
||||
case nsXPTType::T_FLOAT :
|
||||
result++;
|
||||
break;
|
||||
case nsXPTType::T_DOUBLE :
|
||||
result+=2;
|
||||
break;
|
||||
case nsXPTType::T_BOOL :
|
||||
case nsXPTType::T_CHAR :
|
||||
case nsXPTType::T_WCHAR :
|
||||
result++;
|
||||
break;
|
||||
default:
|
||||
// all the others are plain pointer types
|
||||
result++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// nuts, I know there's a cooler way of doing this, but it's late
|
||||
// now and it'll probably come to me in the morning.
|
||||
if (result & 0x3)
|
||||
result += 4 - (result & 0x3); // ensure q-word alignment
|
||||
return result;
|
||||
return (PRUint32)(((paramCount * 2) + 3) & ~3);
|
||||
}
|
||||
|
||||
extern "C" void
|
||||
invoke_copy_to_stack(PRUint32* d, PRUint32 paramCount, nsXPTCVariant* s)
|
||||
invoke_copy_to_stack(PRUint32* d, PRUint32 paramCount, nsXPTCVariant* s,
|
||||
PRUint32* gpregs, double* fpregs)
|
||||
{
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
uint32 *l_d = d;
|
||||
nsXPTCVariant *l_s = s;
|
||||
uint32 l_paramCount = paramCount;
|
||||
uint32 gpr = FIRST_GP_REG + 1; // skip one GP reg for 'this'
|
||||
uint32 fpr = FIRST_FP_REG;
|
||||
|
||||
typedef struct {
|
||||
uint32 hi;
|
||||
uint32 lo;
|
||||
} DU; // have to move 64 bit entities as 32 bit halves since
|
||||
// stack slots are not guaranteed 16 byte aligned
|
||||
|
||||
for(uint32 i = 0; i < l_paramCount; i++, l_d++, l_s++)
|
||||
for(uint32 i = 0; i < paramCount; i++, s++)
|
||||
{
|
||||
if(l_s->IsPtrData())
|
||||
if(s->IsPtrData())
|
||||
{
|
||||
*((void**)l_d) = l_s->ptr;
|
||||
continue;
|
||||
if (gpr > MAX_GP_REG)
|
||||
*((void**) d++) = s->ptr;
|
||||
else
|
||||
{
|
||||
*((void**) gpregs++) = s->ptr;
|
||||
gpr++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
switch(l_s->type)
|
||||
switch(s->type)
|
||||
{
|
||||
case nsXPTType::T_I8 : *((int32*) l_d) = l_s->val.i8; break;
|
||||
case nsXPTType::T_I16 : *((int32*) l_d) = l_s->val.i16; break;
|
||||
case nsXPTType::T_I32 : *((int32*) l_d) = l_s->val.i32; break;
|
||||
case nsXPTType::T_I64 :
|
||||
case nsXPTType::T_U64 :
|
||||
case nsXPTType::T_DOUBLE : *((uint32*) l_d++) = ((DU *)l_s)->hi;
|
||||
*((uint32*) l_d) = ((DU *)l_s)->lo;
|
||||
break;
|
||||
case nsXPTType::T_U8 : *((uint32*) l_d) = l_s->val.u8; break;
|
||||
case nsXPTType::T_U16 : *((uint32*) l_d) = l_s->val.u16; break;
|
||||
case nsXPTType::T_U32 : *((uint32*) l_d) = l_s->val.u32; break;
|
||||
case nsXPTType::T_FLOAT : *((float*) l_d) = l_s->val.f; break;
|
||||
case nsXPTType::T_BOOL : *((PRBool*) l_d) = l_s->val.b; break;
|
||||
case nsXPTType::T_CHAR : *((uint32*) l_d) = l_s->val.c; break;
|
||||
case nsXPTType::T_WCHAR : *((int32*) l_d) = l_s->val.wc; break;
|
||||
case nsXPTType::T_I8:
|
||||
if (gpr > MAX_GP_REG)
|
||||
*((PRInt32*) d++) = s->val.i8;
|
||||
else
|
||||
{
|
||||
*((PRInt32*) gpregs++) = s->val.i8;
|
||||
gpr++;
|
||||
}
|
||||
break;
|
||||
case nsXPTType::T_I16:
|
||||
if (gpr > MAX_GP_REG)
|
||||
*((PRInt32*) d++) = s->val.i16;
|
||||
else
|
||||
{
|
||||
*((PRInt32*) gpregs++) = s->val.i16;
|
||||
gpr++;
|
||||
}
|
||||
break;
|
||||
case nsXPTType::T_I32:
|
||||
if (gpr > MAX_GP_REG)
|
||||
*((PRInt32*) d++) = s->val.i32;
|
||||
else
|
||||
{
|
||||
*((PRInt32*) gpregs++) = s->val.i32;
|
||||
gpr++;
|
||||
}
|
||||
break;
|
||||
case nsXPTType::T_I64:
|
||||
if ((gpr + 1) > MAX_GP_REG)
|
||||
{
|
||||
if (((PRUint32) d) & 4 != 0) d++;
|
||||
*(((PRInt64*) d)++) = s->val.i64;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((gpr & 1) == 0)
|
||||
{
|
||||
gpr++;
|
||||
gpregs++;
|
||||
}
|
||||
*(((PRInt64*) gpregs)++) = s->val.i64;
|
||||
gpr += 2;
|
||||
}
|
||||
break;
|
||||
case nsXPTType::T_U8:
|
||||
if (gpr > MAX_GP_REG)
|
||||
*d++ = s->val.u8;
|
||||
else
|
||||
{
|
||||
*gpregs++ = s->val.u8;
|
||||
gpr++;
|
||||
}
|
||||
break;
|
||||
case nsXPTType::T_U16:
|
||||
if (gpr > MAX_GP_REG)
|
||||
*d++ = s->val.u16;
|
||||
else
|
||||
{
|
||||
*gpregs++ = s->val.u16;
|
||||
gpr++;
|
||||
}
|
||||
break;
|
||||
case nsXPTType::T_U32:
|
||||
if (gpr > MAX_GP_REG)
|
||||
*d++ = s->val.u32;
|
||||
else
|
||||
{
|
||||
*gpregs++ = s->val.u32;
|
||||
gpr++;
|
||||
}
|
||||
break;
|
||||
case nsXPTType::T_U64:
|
||||
if ((gpr + 1) > MAX_GP_REG)
|
||||
{
|
||||
if (((PRUint32) d) & 4 != 0) d++;
|
||||
*(((PRUint64*) d)++) = s->val.u64;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((gpr & 1) == 0)
|
||||
{
|
||||
gpr++;
|
||||
gpregs++;
|
||||
}
|
||||
*(((PRUint64*) gpregs)++) = s->val.u64;
|
||||
gpr += 2;
|
||||
}
|
||||
break;
|
||||
case nsXPTType::T_FLOAT:
|
||||
if (fpr > MAX_FP_REG)
|
||||
*((float*) d++) = s->val.f;
|
||||
else
|
||||
{
|
||||
*fpregs++ = s->val.f;
|
||||
fpr++;
|
||||
}
|
||||
break;
|
||||
case nsXPTType::T_DOUBLE:
|
||||
if (fpr > MAX_FP_REG)
|
||||
{
|
||||
if (((PRUint32) d) & 4 != 0) d++;
|
||||
*(((double*) d)++) = s->val.d;
|
||||
}
|
||||
else
|
||||
{
|
||||
*fpregs++ = s->val.d;
|
||||
fpr++;
|
||||
}
|
||||
break;
|
||||
case nsXPTType::T_BOOL:
|
||||
if (gpr > MAX_GP_REG)
|
||||
*((PRBool*) d++) = s->val.b;
|
||||
else
|
||||
{
|
||||
*((PRBool*) gpregs++) = s->val.b;
|
||||
gpr++;
|
||||
}
|
||||
break;
|
||||
case nsXPTType::T_CHAR:
|
||||
if (gpr > MAX_GP_REG)
|
||||
*d++ = s->val.c;
|
||||
else
|
||||
{
|
||||
*gpregs++ = s->val.c;
|
||||
gpr++;
|
||||
}
|
||||
break;
|
||||
case nsXPTType::T_WCHAR:
|
||||
if (gpr > MAX_GP_REG)
|
||||
*((PRInt32*) d++) = s->val.wc;
|
||||
else
|
||||
{
|
||||
*((PRInt32*) gpregs++) = s->val.wc;
|
||||
gpr++;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// all the others are plain pointer types
|
||||
*((void**)l_d) = l_s->val.p;
|
||||
break;
|
||||
// all the others are plain pointer types
|
||||
if (gpr > MAX_GP_REG)
|
||||
*((void**) d++) = s->val.p;
|
||||
else
|
||||
{
|
||||
*((void**) gpregs++) = s->val.p;
|
||||
gpr++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern "C"
|
||||
XPTC_PUBLIC_API(nsresult)
|
||||
XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex,
|
||||
PRUint32 paramCount, nsXPTCVariant* params);
|
||||
|
||||
@ -21,75 +21,48 @@
|
||||
# Contributor(s):
|
||||
#
|
||||
|
||||
.set r0,0; .set sp,1; .set RTOC,2; .set r3,3; .set r4,4
|
||||
.set r5,5; .set r6,6; .set r7,7; .set r8,8; .set r9,9
|
||||
.set r10,10; .set r11,11; .set r12,12; .set r13,13; .set r14,14
|
||||
.set r15,15; .set r16,16; .set r17,17; .set r18,18; .set r19,19
|
||||
.set r20,20; .set r21,21; .set r22,22; .set r23,23; .set r24,24
|
||||
.set r25,25; .set r26,26; .set r27,27; .set r28,28; .set r29,29
|
||||
.set r30,30; .set r31,31
|
||||
.set f0,0; .set f1,1; .set f2,2; .set f3,3; .set f4,4
|
||||
.set f5,5; .set f6,6; .set f7,7; .set f8,8; .set f9,9
|
||||
.set f10,10; .set f11,11; .set f12,12; .set f13,13; .set f14,14
|
||||
.set f15,15; .set f16,16; .set f17,17; .set f18,18; .set f19,19
|
||||
.set f20,20; .set f21,21; .set f22,22; .set f23,23; .set f24,24
|
||||
.set f25,25; .set f26,26; .set f27,27; .set f28,28; .set f29,29
|
||||
.set f30,30; .set f31,31
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# .text section
|
||||
|
||||
.globl SharedStub
|
||||
.extern PrepareAndDispatch
|
||||
|
||||
|
||||
#
|
||||
# on entry SharedStub has the method selector in r12, the rest of the original
|
||||
# parameters are in r3 thru r10 and f1 thru f13
|
||||
#
|
||||
|
||||
.section ".text"
|
||||
.align 2
|
||||
.globl SharedStub
|
||||
.type SharedStub,@function
|
||||
|
||||
SharedStub:
|
||||
mflr r0
|
||||
stw r0,8(sp)
|
||||
stwu 1,-112(1) # room for
|
||||
# linkage (8),
|
||||
# gprData (32),
|
||||
# fprData (64),
|
||||
# stack alignment(8)
|
||||
|
||||
stwu sp,-176(sp) # room for linkage (24), fprData (104), gprData(28)
|
||||
# outgoing params to PrepareAndDispatch (20)
|
||||
mflr 0
|
||||
stw 0,116(1)
|
||||
|
||||
stw r4,44(sp)
|
||||
stw r5,48(sp)
|
||||
stw r6,52(sp)
|
||||
stw r7,56(sp)
|
||||
stw r8,60(sp)
|
||||
stw r9,64(sp)
|
||||
stw r10,68(sp)
|
||||
stfd f1,72(sp)
|
||||
stfd f2,80(sp)
|
||||
stfd f3,88(sp)
|
||||
stfd f4,96(sp)
|
||||
stfd f5,104(sp)
|
||||
stfd f6,112(sp)
|
||||
stfd f7,120(sp)
|
||||
stfd f8,128(sp)
|
||||
stfd f9,136(sp)
|
||||
stfd f10,144(sp)
|
||||
stfd f11,152(sp)
|
||||
stfd f12,156(sp)
|
||||
stfd f13,164(sp)
|
||||
stw 4,12(1) # save GP registers
|
||||
stw 5,16(1)
|
||||
stw 6,20(1)
|
||||
stw 7,24(1)
|
||||
stw 8,28(1)
|
||||
stw 9,32(1)
|
||||
stw 10,36(1)
|
||||
|
||||
stfd 1,40(1) # save FP registers
|
||||
stfd 2,48(1)
|
||||
stfd 3,56(1)
|
||||
stfd 4,64(1)
|
||||
stfd 5,72(1)
|
||||
stfd 6,80(1)
|
||||
stfd 7,88(1)
|
||||
stfd 8,96(1)
|
||||
|
||||
addi r6,sp,44 # gprData
|
||||
addi r7,sp,72 # fprData
|
||||
# r3 has the 'self' pointer already
|
||||
# mr r4,r12 # methodIndex selector
|
||||
addi r5,sp,232 # pointer to callers args area, beyond r3-r10 mapped range
|
||||
# r4 has the 'methodIndex' selector
|
||||
addi 5,1,120 # pointer to callers args area, beyond r3-r10/f1-f8 mapped range
|
||||
addi 6,1,12 # gprData+1
|
||||
addi 7,1,40 # fprData
|
||||
|
||||
bl PrepareAndDispatch
|
||||
nop
|
||||
|
||||
lwz r0,184(sp)
|
||||
addi sp,sp,176
|
||||
mtlr r0
|
||||
lwz 0,116(1)
|
||||
mtlr 0
|
||||
la 1,112(1)
|
||||
blr
|
||||
|
||||
|
||||
@ -25,170 +25,228 @@
|
||||
#include "xptcprivate.h"
|
||||
|
||||
/*
|
||||
For PPC (AIX & MAC), the first 8 integral and the first 13 f.p. parameters
|
||||
For Linux/PPC, the first 8 integral and the first 8 f.p. parameters
|
||||
arrive in a separate chunk of data that has been loaded from the registers.
|
||||
The args pointer has been set to the start of the parameters BEYOND the ones
|
||||
arriving in registers
|
||||
arriving in registers.
|
||||
*/
|
||||
|
||||
extern "C" nsresult
|
||||
PrepareAndDispatch(nsXPTCStubBase* self, PRUint32 methodIndex, PRUint32* args, PRUint32 *gprData, double *fprData)
|
||||
{
|
||||
typedef struct {
|
||||
uint32 hi;
|
||||
uint32 lo; // have to move 64 bit entities as 32 bit halves since
|
||||
} DU; // stack slots are not guaranteed 16 byte aligned
|
||||
|
||||
#define PARAM_BUFFER_COUNT 16
|
||||
#define PARAM_GPR_COUNT 7
|
||||
#define PARAM_GPR_COUNT 8
|
||||
#define PARAM_FPR_COUNT 8
|
||||
|
||||
nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
|
||||
nsXPTCMiniVariant* dispatchParams = NULL;
|
||||
nsIInterfaceInfo* iface_info = NULL;
|
||||
const nsXPTMethodInfo* info;
|
||||
PRUint8 paramCount;
|
||||
PRUint8 i;
|
||||
nsresult result = NS_ERROR_FAILURE;
|
||||
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");
|
||||
NS_ASSERTION(self,"no self");
|
||||
|
||||
self->GetInterfaceInfo(&iface_info);
|
||||
NS_ASSERTION(iface_info,"no interface info");
|
||||
self->GetInterfaceInfo(&iface_info);
|
||||
NS_ASSERTION(iface_info,"no interface info");
|
||||
|
||||
iface_info->GetMethodInfo(PRUint16(methodIndex), &info);
|
||||
NS_ASSERTION(info,"no interface info");
|
||||
iface_info->GetMethodInfo(PRUint16(methodIndex), &info);
|
||||
NS_ASSERTION(info,"no interface info");
|
||||
|
||||
paramCount = info->GetParamCount();
|
||||
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");
|
||||
// setup variant array pointer
|
||||
if(paramCount > PARAM_BUFFER_COUNT)
|
||||
dispatchParams = new nsXPTCMiniVariant[paramCount];
|
||||
else
|
||||
dispatchParams = paramBuffer;
|
||||
NS_ASSERTION(dispatchParams,"no place for params");
|
||||
|
||||
PRUint32* ap = args;
|
||||
PRUint32 iCount = 0;
|
||||
PRUint32 fpCount = 0;
|
||||
for(i = 0; i < paramCount; i++)
|
||||
PRUint32* ap = args;
|
||||
PRUint32 gprCount = 1; //skip one GPR reg
|
||||
PRUint32 fprCount = 0;
|
||||
for(i = 0; i < paramCount; i++)
|
||||
{
|
||||
const nsXPTParamInfo& param = info->GetParam(i);
|
||||
const nsXPTType& type = param.GetType();
|
||||
nsXPTCMiniVariant* dp = &dispatchParams[i];
|
||||
const nsXPTParamInfo& param = info->GetParam(i);
|
||||
const nsXPTType& type = param.GetType();
|
||||
nsXPTCMiniVariant* dp = &dispatchParams[i];
|
||||
|
||||
if(param.IsOut() || !type.IsArithmetic())
|
||||
if(param.IsOut() || !type.IsArithmetic())
|
||||
{
|
||||
if (iCount < PARAM_GPR_COUNT)
|
||||
dp->val.p = (void*) gprData[iCount++];
|
||||
else
|
||||
dp->val.p = (void*) *ap++;
|
||||
continue;
|
||||
if (gprCount < PARAM_GPR_COUNT)
|
||||
{
|
||||
dp->val.p = (void*) *gprData++;
|
||||
gprCount++;
|
||||
}
|
||||
else
|
||||
dp->val.p = (void*) *ap++;
|
||||
continue;
|
||||
}
|
||||
// else
|
||||
switch(type)
|
||||
// else
|
||||
switch(type)
|
||||
{
|
||||
case nsXPTType::T_I8 : if (iCount < PARAM_GPR_COUNT)
|
||||
dp->val.i8 = (PRInt8) gprData[iCount++];
|
||||
else
|
||||
dp->val.i8 = (PRInt8) *ap++;
|
||||
break;
|
||||
case nsXPTType::T_I16 : if (iCount < PARAM_GPR_COUNT)
|
||||
dp->val.i16 = (PRInt16) gprData[iCount++];
|
||||
else
|
||||
dp->val.i16 = (PRInt16) *ap++;
|
||||
break;
|
||||
case nsXPTType::T_I32 : if (iCount < PARAM_GPR_COUNT)
|
||||
dp->val.i32 = (PRInt32) gprData[iCount++];
|
||||
else
|
||||
dp->val.i32 = (PRInt32) *ap++;
|
||||
break;
|
||||
case nsXPTType::T_I64 : if (iCount < PARAM_GPR_COUNT)
|
||||
((DU *)dp)->hi = (PRInt32) gprData[iCount++];
|
||||
else
|
||||
((DU *)dp)->hi = (PRInt32) *ap++;
|
||||
if (iCount < PARAM_GPR_COUNT)
|
||||
((DU *)dp)->lo = (PRUint32) gprData[iCount++];
|
||||
else
|
||||
((DU *)dp)->lo = (PRUint32) *ap++;
|
||||
break;
|
||||
case nsXPTType::T_U8 : if (iCount < PARAM_GPR_COUNT)
|
||||
dp->val.i8 = (PRUint8) gprData[iCount++];
|
||||
else
|
||||
dp->val.i8 = (PRUint8) *ap++;
|
||||
break;
|
||||
case nsXPTType::T_U16 : if (iCount < PARAM_GPR_COUNT)
|
||||
dp->val.i16 = (PRUint16) gprData[iCount++];
|
||||
else
|
||||
dp->val.i16 = (PRUint16) *ap++;
|
||||
break;
|
||||
case nsXPTType::T_U32 : if (iCount < PARAM_GPR_COUNT)
|
||||
dp->val.i32 = (PRUint32) gprData[iCount++];
|
||||
else
|
||||
dp->val.i32 = (PRUint32) *ap++;
|
||||
break;
|
||||
case nsXPTType::T_U64 : if (iCount < PARAM_GPR_COUNT)
|
||||
((DU *)dp)->hi = (PRUint32) gprData[iCount++];
|
||||
else
|
||||
((DU *)dp)->hi = (PRUint32) *ap++;
|
||||
if (iCount < PARAM_GPR_COUNT)
|
||||
((DU *)dp)->lo = (PRUint32) gprData[iCount++];
|
||||
else
|
||||
((DU *)dp)->lo = (PRUint32) *ap++;
|
||||
break;
|
||||
case nsXPTType::T_FLOAT : if (fpCount < 13) {
|
||||
dp->val.f = (float) fprData[fpCount++];
|
||||
if (iCount < PARAM_GPR_COUNT)
|
||||
++iCount;
|
||||
else
|
||||
++ap;
|
||||
}
|
||||
else
|
||||
dp->val.f = *((float*) ap++);
|
||||
break;
|
||||
case nsXPTType::T_DOUBLE : if (fpCount < 13) {
|
||||
dp->val.d = (double) fprData[fpCount++];
|
||||
if (iCount < PARAM_GPR_COUNT)
|
||||
++iCount;
|
||||
else
|
||||
++ap;
|
||||
if (iCount < PARAM_GPR_COUNT)
|
||||
++iCount;
|
||||
else
|
||||
++ap;
|
||||
}
|
||||
else {
|
||||
dp->val.f = *((double*) ap);
|
||||
ap += 2;
|
||||
}
|
||||
break;
|
||||
case nsXPTType::T_BOOL : if (iCount < PARAM_GPR_COUNT)
|
||||
dp->val.b = (PRBool) gprData[iCount++];
|
||||
else
|
||||
dp->val.b = (PRBool) *ap++;
|
||||
break;
|
||||
case nsXPTType::T_CHAR : if (iCount < PARAM_GPR_COUNT)
|
||||
dp->val.c = (char) gprData[iCount++];
|
||||
else
|
||||
dp->val.c = (char) *ap++;
|
||||
break;
|
||||
case nsXPTType::T_WCHAR : if (iCount < PARAM_GPR_COUNT)
|
||||
dp->val.wc = (wchar_t) gprData[iCount++];
|
||||
else
|
||||
dp->val.wc = (wchar_t) *ap++;
|
||||
break;
|
||||
default:
|
||||
NS_ASSERTION(0, "bad type");
|
||||
break;
|
||||
case nsXPTType::T_I8:
|
||||
if (gprCount < PARAM_GPR_COUNT)
|
||||
{
|
||||
dp->val.i8 = (PRInt8) *gprData++;
|
||||
gprCount++;
|
||||
}
|
||||
else
|
||||
dp->val.i8 = (PRInt8) *ap++;
|
||||
break;
|
||||
|
||||
case nsXPTType::T_I16:
|
||||
if (gprCount < PARAM_GPR_COUNT)
|
||||
{
|
||||
dp->val.i16 = (PRInt16) *gprData++;
|
||||
gprCount++;
|
||||
}
|
||||
else
|
||||
dp->val.i16 = (PRInt16) *ap++;
|
||||
break;
|
||||
|
||||
case nsXPTType::T_I32:
|
||||
if (gprCount < PARAM_GPR_COUNT)
|
||||
{
|
||||
dp->val.i32 = (PRInt32) *gprData++;
|
||||
gprCount++;
|
||||
}
|
||||
else
|
||||
dp->val.i32 = (PRInt32) *ap++;
|
||||
break;
|
||||
|
||||
case nsXPTType::T_I64:
|
||||
if (gprCount & 1) gprCount++;
|
||||
if ((gprCount + 1) < PARAM_GPR_COUNT)
|
||||
{
|
||||
dp->val.i64 = *(PRInt64*) gprData;
|
||||
gprData += 2;
|
||||
gprCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((PRUint32) ap & 4) ap++;
|
||||
dp->val.i64 = *(PRInt64*) ap;
|
||||
ap += 2;
|
||||
}
|
||||
break;
|
||||
|
||||
case nsXPTType::T_U8:
|
||||
if (gprCount < PARAM_GPR_COUNT)
|
||||
{
|
||||
dp->val.u8 = (PRUint8) *gprData++;
|
||||
gprCount++;
|
||||
}
|
||||
else
|
||||
dp->val.u8 = (PRUint8) *ap++;
|
||||
break;
|
||||
|
||||
case nsXPTType::T_U16:
|
||||
if (gprCount < PARAM_GPR_COUNT)
|
||||
{
|
||||
dp->val.u16 = (PRUint16) *gprData++;
|
||||
gprCount++;
|
||||
}
|
||||
else
|
||||
dp->val.u16 = (PRUint16) *ap++;
|
||||
break;
|
||||
|
||||
case nsXPTType::T_U32:
|
||||
if (gprCount < PARAM_GPR_COUNT)
|
||||
{
|
||||
dp->val.u32 = (PRUint32) *gprData++;
|
||||
gprCount++;
|
||||
}
|
||||
else
|
||||
dp->val.u32 = (PRUint32) *ap++;
|
||||
break;
|
||||
|
||||
case nsXPTType::T_U64:
|
||||
if (gprCount & 1) gprCount++;
|
||||
if ((gprCount + 1) < PARAM_GPR_COUNT)
|
||||
{
|
||||
dp->val.u64 = *(PRUint64*) gprData;
|
||||
gprData += 2;
|
||||
gprCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((PRUint32) ap & 4) ap++;
|
||||
dp->val.u64 = *(PRUint64*) ap;
|
||||
ap += 2;
|
||||
}
|
||||
break;
|
||||
|
||||
case nsXPTType::T_FLOAT:
|
||||
if (fprCount < PARAM_FPR_COUNT)
|
||||
{
|
||||
dp->val.f = (float) *fprData++;
|
||||
fprCount++;
|
||||
}
|
||||
else
|
||||
dp->val.f = *(float*) ap++;
|
||||
break;
|
||||
|
||||
case nsXPTType::T_DOUBLE:
|
||||
if (fprCount < PARAM_FPR_COUNT)
|
||||
{
|
||||
dp->val.d = *fprData++;
|
||||
fprCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((PRUint32) ap & 4) ap++;
|
||||
dp->val.d = *(double*) ap;
|
||||
ap += 2;
|
||||
}
|
||||
break;
|
||||
|
||||
case nsXPTType::T_BOOL:
|
||||
if (gprCount < PARAM_GPR_COUNT)
|
||||
{
|
||||
dp->val.b = (PRBool) *gprData++;
|
||||
gprCount++;
|
||||
}
|
||||
else
|
||||
dp->val.b = (PRBool) *ap++;
|
||||
break;
|
||||
|
||||
case nsXPTType::T_CHAR:
|
||||
if (gprCount < PARAM_GPR_COUNT)
|
||||
{
|
||||
dp->val.c = (char) *gprData++;
|
||||
gprCount++;
|
||||
}
|
||||
else
|
||||
dp->val.c = (char) *ap++;
|
||||
break;
|
||||
|
||||
case nsXPTType::T_WCHAR:
|
||||
if (gprCount < PARAM_GPR_COUNT)
|
||||
{
|
||||
dp->val.wc = (wchar_t) *gprData++;
|
||||
gprCount++;
|
||||
}
|
||||
else
|
||||
dp->val.wc = (wchar_t) *ap++;
|
||||
break;
|
||||
|
||||
default:
|
||||
NS_ASSERTION(0, "bad type");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
result = self->CallMethod((PRUint16)methodIndex, info, dispatchParams);
|
||||
result = self->CallMethod((PRUint16) methodIndex, info, dispatchParams);
|
||||
|
||||
NS_RELEASE(iface_info);
|
||||
NS_RELEASE(iface_info);
|
||||
|
||||
if(dispatchParams != paramBuffer)
|
||||
delete [] dispatchParams;
|
||||
if(dispatchParams != paramBuffer)
|
||||
delete [] dispatchParams;
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
extern "C" int SharedStub(void *, int);
|
||||
@ -196,14 +254,14 @@ extern "C" int SharedStub(void *, int);
|
||||
#define STUB_ENTRY(n) \
|
||||
nsresult nsXPTCStubBase::Stub##n() \
|
||||
{ \
|
||||
return SharedStub(this, n); \
|
||||
} \
|
||||
return SharedStub(this, n); \
|
||||
}
|
||||
|
||||
#define SENTINEL_ENTRY(n) \
|
||||
nsresult nsXPTCStubBase::Sentinel##n() \
|
||||
{ \
|
||||
NS_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \
|
||||
return NS_ERROR_NOT_IMPLEMENTED; \
|
||||
#define SENTINEL_ENTRY(n) \
|
||||
nsresult nsXPTCStubBase::Sentinel##n() \
|
||||
{ \
|
||||
NS_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \
|
||||
return NS_ERROR_NOT_IMPLEMENTED; \
|
||||
}
|
||||
|
||||
#include "xptcstubsdef.inc"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user