Pretty up Franz Sirl's code; fix STUB_ENTRY() macro to use r12 as the register in which the method index is passed; r4 is used for passing the first parameter! r=beard@netscape.com (actually, most of the work was beard!)

This commit is contained in:
waterson%netscape.com 1999-12-07 02:05:54 +00:00
Родитель d3e415dbf5
Коммит 91a44351d9
4 изменённых файлов: 289 добавлений и 256 удалений

Просмотреть файл

@ -20,6 +20,20 @@
#
# 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
.section ".text"
.align 2
@ -32,62 +46,62 @@
#
XPTC_InvokeByIndex:
stwu 1,-32(1)
mflr 0
stw 3,8(1) # that
stw 4,12(1) # methodIndex
stw 30,16(1)
stw 31,20(1)
stwu sp,-32(sp)
mflr r0
stw r3,8(sp) # that
stw r4,12(sp) # methodIndex
stw r30,16(sp)
stw r31,20(sp)
stw 0,36(1)
mr 31,1
stw r0,36(sp)
mr r31,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
slwi r10,r5,3 # reserve stack for ParamCount *2 *4
addi r0,r10,128 # reserve stack for GPR and FPR
lwz r9,0(sp)
neg r0,r0
stwux r9,sp,r0
addi r3,sp,8 # args
mr r4,r5 # paramCount
mr r5,r6 # params
add r6,r3,r10 # gpregs
mr r30,r6
addi r7,r6,32 # fpregs
bl invoke_copy_to_stack # (args, paramCount, params, gpregs, fpregs)
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)
lfd f1,32(r30) # load FP registers
lfd f2,40(r30)
lfd f3,48(r30)
lfd f4,56(r30)
lfd f5,64(r30)
lfd f6,72(r30)
lfd f7,80(r30)
lfd f8,88(r30)
lwz 3,8(31) # that
lwz 4,12(31) # methodIndex
lwz r3,8(r31) # that
lwz r4,12(r31) # 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 r5,0(r3) # vtable
slwi r4,r4,2 # temp = methodIndex * 4
addi r4,r4,8 # temp += 8
lwzx r0,r4,r5 # 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)
lwz r4,0(r30) # load GP regs
lwz r5,4(r30)
lwz r6,8(r30)
lwz r7,12(r30)
lwz r8,16(r30)
lwz r9,20(r30)
lwz r10,24(r30)
mtlr 0
blrl # call
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
lwz r30,16(r31) # clean up stack
lwz r31,20(r31)
lwz r11,0(sp)
lwz r0,4(r11)
mtlr r0
mr sp,r11
blr

Просмотреть файл

@ -89,8 +89,8 @@ invoke_copy_to_stack(PRUint32* d, PRUint32 paramCount, nsXPTCVariant* s,
case nsXPTType::T_I64:
if ((gpr + 1) > MAX_GP_REG)
{
if (((PRUint32) d) & 4 != 0) d++;
*(((PRInt64*) d)++) = s->val.i64;
if (PRUint32(d) & 4) d++;
*(((PRInt64*&) d)++) = s->val.i64;
}
else
{
@ -99,7 +99,7 @@ invoke_copy_to_stack(PRUint32* d, PRUint32 paramCount, nsXPTCVariant* s,
gpr++;
gpregs++;
}
*(((PRInt64*) gpregs)++) = s->val.i64;
*(((PRInt64*&) gpregs)++) = s->val.i64;
gpr += 2;
}
break;
@ -133,8 +133,8 @@ invoke_copy_to_stack(PRUint32* d, PRUint32 paramCount, nsXPTCVariant* s,
case nsXPTType::T_U64:
if ((gpr + 1) > MAX_GP_REG)
{
if (((PRUint32) d) & 4 != 0) d++;
*(((PRUint64*) d)++) = s->val.u64;
if (PRUint32(d) & 4) d++;
*(((PRUint64*&) d)++) = s->val.u64;
}
else
{
@ -143,7 +143,7 @@ invoke_copy_to_stack(PRUint32* d, PRUint32 paramCount, nsXPTCVariant* s,
gpr++;
gpregs++;
}
*(((PRUint64*) gpregs)++) = s->val.u64;
*(((PRUint64*&) gpregs)++) = s->val.u64;
gpr += 2;
}
break;
@ -159,8 +159,8 @@ invoke_copy_to_stack(PRUint32* d, PRUint32 paramCount, nsXPTCVariant* s,
case nsXPTType::T_DOUBLE:
if (fpr > MAX_FP_REG)
{
if (((PRUint32) d) & 4 != 0) d++;
*(((double*) d)++) = s->val.d;
if (PRUint32(d) & 4) d++;
*(((double*&) d)++) = s->val.d;
}
else
{

Просмотреть файл

@ -21,48 +21,66 @@
# 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
.section ".text"
.align 2
.globl SharedStub
.type SharedStub,@function
SharedStub:
stwu 1,-112(1) # room for
mflr r0
stw r0,4(sp)
stwu sp,-112(sp) # room for
# linkage (8),
# gprData (32),
# fprData (64),
# stack alignment(8)
mflr 0
stw 0,116(1)
stw r4,12(sp) # save GP registers
stw r5,16(sp)
stw r6,20(sp)
stw r7,24(sp)
stw r8,28(sp)
stw r9,32(sp)
stw r10,36(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)
stfd f1,40(sp) # save FP registers
stfd f2,48(sp)
stfd f3,56(sp)
stfd f4,64(sp)
stfd f5,72(sp)
stfd f6,80(sp)
stfd f7,88(sp)
stfd f8,96(sp)
# r3 has the 'self' pointer already
# 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
mr r4,r12 # r4 is expected to have the 'methodIndex' selector
addi r5,sp,120 # pointer to callers args area, beyond r3-r10/f1-f8 mapped range
addi r6,sp,12 # gprData+1
addi r7,sp,40 # fprData
bl PrepareAndDispatch
lwz 0,116(1)
mtlr 0
la 1,112(1)
lwz r0,116(sp)
mtlr r0
# la sp,112(sp)
lwz sp,0(sp)
blr

Просмотреть файл

@ -67,177 +67,172 @@ PrepareAndDispatch(nsXPTCStubBase* self, PRUint32 methodIndex, PRUint32* args, P
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];
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 (gprCount < PARAM_GPR_COUNT)
{
dp->val.p = (void*) *gprData++;
gprCount++;
}
else
dp->val.p = (void*) *ap++;
continue;
}
// else
switch(type)
{
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;
}
if(param.IsOut() || !type.IsArithmetic()) {
if (gprCount < PARAM_GPR_COUNT) {
dp->val.p = (void*) *gprData++;
gprCount++;
}
else {
dp->val.p = (void*) *ap++;
}
continue;
}
// else
switch(type) {
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);
@ -249,12 +244,18 @@ PrepareAndDispatch(nsXPTCStubBase* self, PRUint32 methodIndex, PRUint32* args, P
return result;
}
extern "C" int SharedStub(void *, int);
// We give a bogus prototype to generate the correct glue code. We
// actually pass the method index in r12 (an "unused" register),
// because r4 is used to pass the first parameter.
extern "C" nsresult SharedStub(void);
#define STUB_ENTRY(n) \
nsresult nsXPTCStubBase::Stub##n() \
{ \
return SharedStub(this, n); \
__asm__( \
"\tli 12,"#n"\n" \
); \
return SharedStub(); \
}
#define SENTINEL_ENTRY(n) \