From d70dfd81465bf2a2a6f0ce42557fda1d1a3471a3 Mon Sep 17 00:00:00 2001 From: "mgleeson1%netscape.com" Date: Thu, 19 Aug 1999 20:36:06 +0000 Subject: [PATCH] HP-UX additions git-svn-id: svn://10.0.0.236/trunk@43668 18797224-902f-48f8-a5cc-f745e15eee43 --- .../reflect/xptcall/src/md/unix/Makefile.in | 12 ++ .../xptcall/src/md/unix/xptcinvoke_asm_pa32.s | 131 ++++++++++++++ .../xptcall/src/md/unix/xptcinvoke_pa32.cpp | 161 ++++++++++++++++++ .../xptcall/src/md/unix/xptcstubs_asm_pa32.s | 68 ++++++++ .../xptcall/src/md/unix/xptcstubs_pa32.cpp | 156 +++++++++++++++++ 5 files changed, 528 insertions(+) create mode 100644 mozilla/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_pa32.s create mode 100644 mozilla/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_pa32.cpp create mode 100644 mozilla/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_pa32.s create mode 100644 mozilla/xpcom/reflect/xptcall/src/md/unix/xptcstubs_pa32.cpp diff --git a/mozilla/xpcom/reflect/xptcall/src/md/unix/Makefile.in b/mozilla/xpcom/reflect/xptcall/src/md/unix/Makefile.in index 216e1880ef7..4ed8849ebb8 100644 --- a/mozilla/xpcom/reflect/xptcall/src/md/unix/Makefile.in +++ b/mozilla/xpcom/reflect/xptcall/src/md/unix/Makefile.in @@ -103,6 +103,18 @@ CPPSRCS = \ endif endif +# HP-UX/PA32 +ifeq ($(OS_ARCH),HP-UX) +CPPSRCS = \ + xptcinvoke_pa32.cpp \ + xptcstubs_pa32.cpp \ + $(NULL) +ASFILES = \ + xptcstubs_asm_pa32.s \ + xptcinvoke_asm_pa32.s \ + $(NULL) +endif + # AIX/PPC ifeq ($(OS_ARCH),AIX) CPPSRCS = \ diff --git a/mozilla/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_pa32.s b/mozilla/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_pa32.s new file mode 100644 index 00000000000..8ce8f17f8c1 --- /dev/null +++ b/mozilla/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_pa32.s @@ -0,0 +1,131 @@ + .LEVEL 1.1 +framesz .EQU 128 + +; XPTC_InvokeByIndex(nsISuppots* that, PRUint32 methodIndex, +; PRUint32 paramCount, nsXPTCVariant* params); + +; g++ need to compile everything with -fvtable-thunks ! + + .SPACE $TEXT$,SORT=8 + .SUBSPA $CODE$,QUAD=0,ALIGN=4,ACCESS=0x2c,CODE_ONLY,SORT=24 +XPTC_InvokeByIndex + .PROC + .CALLINFO CALLER,FRAME=72,ENTRY_GR=%r3,SAVE_RP,SAVE_SP,ARGS_SAVED,ALLOCA_FRAME + + ; frame marker takes 48 bytes, + ; register spill area takes 8 bytes, + ; local stack area takes 72 bytes result in 128 bytes total + + .ENTRY + STW %rp,-20(%sp) + STW,MA %r3,128(%sp) + + LDO -framesz(%r30),%r28 + STW %r28,-4(%r30) ; save previous sp + STW %r19,-32(%r30) + + STW %r26,-36-framesz(%r30) ; save argument registers in + STW %r25,-40-framesz(%r30) ; in PREVIOUS frame + STW %r24,-44-framesz(%r30) ; + STW %r23,-48-framesz(%r30) ; + + B,L .+8,%r2 + ADDIL L'invoke_count_bytes-$PIC_pcrel$1+4,%r2,%r1 + LDO R'invoke_count_bytes-$PIC_pcrel$2+8(%r1),%r1 +$PIC_pcrel$1 + LDSID (%r1),%r31 +$PIC_pcrel$2 + MTSP %r31,%sr0 + .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR ;in=24,25,26;out=28 + BE,L 0(%sr0,%r1),%r31 + COPY %r31,%r2 + + CMPIB,>= 0,%r28, .+76 + COPY %r30,%r3 ; copy stack ptr to saved stack ptr + ADD %r30,%r28,%r30 ; extend stack frame + LDW -4(%r3),%r28 ; move frame + STW %r28,-4(%r30) + LDW -8(%r3),%r28 + STW %r28,-8(%r30) + LDW -12(%r3),%r28 + STW %r28,-12(%r30) + LDW -16(%r3),%r28 + STW %r28,-16(%r30) + LDW -20(%r3),%r28 + STW %r28,-20(%r30) + LDW -24(%r3),%r28 + STW %r28,-24(%r30) + LDW -28(%r3),%r28 + STW %r28,-28(%r30) + LDW -32(%r3),%r28 + STW %r28,-32(%r30) + + LDO -40(%r30),%r26 ; load copy address + LDW -44-framesz(%r3),%r25 ; load rest of 2 arguments + LDW -48-framesz(%r3),%r24 ; + + LDW -32(%r30),%r19 ; shared lib call destroys r19; reload + B,L .+8,%r2 + ADDIL L'invoke_copy_to_stack-$PIC_pcrel$3+4,%r2,%r1 + LDO R'invoke_copy_to_stack-$PIC_pcrel$4+8(%r1),%r1 +$PIC_pcrel$3 + LDSID (%r1),%r31 +$PIC_pcrel$4 + MTSP %r31,%sr0 + .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR ;in=24,25,26 + BE,L 0(%sr0,%r1),%r31 + COPY %r31,%r2 + + LDO -48(%r30),%r20 + EXTRW,U,= %r28,31,1,%r22 + FLDD 0(%r20),%fr7 ; load double arg 1 + EXTRW,U,= %r28,30,1,%r22 + FLDW 8(%r20),%fr5L ; load float arg 1 + EXTRW,U,= %r28,29,1,%r22 + FLDW 4(%r20),%fr6L ; load float arg 2 + EXTRW,U,= %r28,28,1,%r22 + FLDW 0(%r20),%fr7L ; load float arg 3 + + LDW -36-framesz(%r3),%r26 ; load ptr to 'that' + LDW -40(%r30),%r25 ; load the rest of dispatch argument registers + LDW -44(%r30),%r24 + LDW -48(%r30),%r23 + + LDW -36-framesz(%r3),%r20 ; load vtable addr + LDW -40-framesz(%r3),%r28 ; load index + LDW 0(%r20),%r20 ; follow vtable + LDO 16(%r20),%r20 ; offset vtable by 16 bytes (g++: 8, aCC: 16) + SH2ADDL %r28,%r20,%r28 ; add 4*index to vtable entry + LDW 0(%r28),%r22 ; load vtable entry + + B,L .+8,%r2 + ADDIL L'$$dyncall_external-$PIC_pcrel$5+4,%r2,%r1 + LDO R'$$dyncall_external-$PIC_pcrel$6+8(%r1),%r1 +$PIC_pcrel$5 + LDSID (%r1),%r31 +$PIC_pcrel$6 + MTSP %r31,%sr0 + .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR,RTNVAL=GR +;in=22-26;out=28; + BE,L 0(%sr0,%r1),%r31 + COPY %r31,%r2 + + LDW -32(%r30),%r19 + COPY %r3,%r30 ; restore saved stack ptr + + LDW -148(%sp),%rp + BVE (%rp) + .EXIT + LDW,MB -128(%sp),%r3 + + .PROCEND ;in=23,24,25,26; + + .ALIGN 8 + .SPACE $TEXT$ + .SUBSPA $CODE$ + .IMPORT $$dyncall_external,MILLICODE + .IMPORT invoke_count_bytes,CODE + .IMPORT invoke_copy_to_stack,CODE + .EXPORT XPTC_InvokeByIndex,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR,RTNVAL=GR,LONG_RETURN + .END + diff --git a/mozilla/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_pa32.cpp b/mozilla/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_pa32.cpp new file mode 100644 index 00000000000..20e40257a7f --- /dev/null +++ b/mozilla/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_pa32.cpp @@ -0,0 +1,161 @@ + +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1999 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "xptcprivate.h" + +#if _HPUX +#error "This code is for HP-PA RISC 32 bit mode only" +#endif + +#include + +typedef unsigned nsXPCVariant; + +extern "C" PRInt32 +invoke_count_bytes(nsISupports* that, + const PRUint32 paramCount, const nsXPTCVariant* s) +{ + PRInt32 result = 4; /* variant records do not include self pointer */ + + /* counts the number of bytes required by the argument stack, + 64 bit integer, and double requires 8 bytes. All else requires + 4 bytes. + */ + + { + PRUint32 indx; + for (indx = paramCount; indx > 0; --indx, ++s) + { + if (! s->IsPtrData()) + { + if (s->type == nsXPTType::T_I64 || s->type == nsXPTType::T_U64 || + s->type == nsXPTType::T_DOUBLE) + { + /* 64 bit integer and double aligned on 8 byte boundaries */ + result += (result & 4) + 8; + continue; + } + } + result += 4; /* all other cases use 4 bytes */ + } + } + result -= 72; /* existing stack buffer is 72 bytes */ + if (result < 0) + return 0; + { + /* round up to 64 bytes boundary */ + PRInt32 remainder = result & 63; + return (remainder == 0) ? result : (result + 64 - remainder); + } +} + +extern "C" PRUint32 +invoke_copy_to_stack(PRUint32* d, + const PRUint32 paramCount, nsXPTCVariant* s) +{ + + typedef struct + { + PRUint32 hi; + PRUint32 lo; + } DU; + + PRUint32* dest = d; + nsXPTCVariant* source = s; + /* we clobber param vars by copying stuff on stack, have to use local var */ + + PRUint32 floatflags = 0; + /* flag indicating which floating point registers to load */ + + PRUint32 regwords = 1; /* register 26 is reserved for ptr to 'that' */ + PRUint32 indx; + + for (indx = paramCount; indx > 0; --indx, --dest, ++source) + { + if (source->IsPtrData()) + { + *((void**) dest) = source->ptr; + ++regwords; + continue; + } + switch (source->type) + { + case nsXPTType::T_I8 : *((PRInt32*) dest) = source->val.i8; break; + case nsXPTType::T_I16 : *((PRInt32*) dest) = source->val.i16; break; + case nsXPTType::T_I32 : *((PRInt32*) dest) = source->val.i32; break; + case nsXPTType::T_I64 : + case nsXPTType::T_U64 : + if (regwords & 1) + { + /* align on double word boundary */ + --dest; + ++regwords; + } + *((uint32*) dest) = ((DU *) source)->lo; + *((uint32*) --dest) = ((DU *) source)->hi; + /* big endian - hi word in low addr */ + regwords += 2; + continue; + case nsXPTType::T_DOUBLE : + if (regwords & 1) + { + /* align on double word boundary */ + --dest; + ++regwords; + } + switch (regwords) /* load double precision float register */ + { + case 2: + floatflags |= 1; + } + *((uint32*) dest) = ((DU *) source)->lo; + *((uint32*) --dest) = ((DU *) source)->hi; + /* big endian - hi word in low addr */ + regwords += 2; + continue; + case nsXPTType::T_FLOAT : + switch (regwords) /* load single precision float register */ + { + case 1: + floatflags |= 2; + break; + case 2: + floatflags |= 4; + break; + case 3: + floatflags |= 8; + } + *((float*) dest) = source->val.f; + break; + case nsXPTType::T_U8 : *((PRUint32*) (dest)) = source->val.u8; break; + case nsXPTType::T_U16 : *((PRUint32*) (dest)) = source->val.u16; break; + case nsXPTType::T_U32 : *((PRUint32*) (dest)) = source->val.u32; break; + case nsXPTType::T_BOOL : *((PRBool*) (dest)) = source->val.b; break; + case nsXPTType::T_CHAR : *((PRUint32*) (dest)) = source->val.c; break; + case nsXPTType::T_WCHAR : *((PRInt32*) (dest)) = source->val.wc; break; + + default: + // all the others are plain pointer types + *((void**) dest) = source->val.p; + } + ++regwords; + } + return floatflags; +} + diff --git a/mozilla/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_pa32.s b/mozilla/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_pa32.s new file mode 100644 index 00000000000..9e86848fcfa --- /dev/null +++ b/mozilla/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_pa32.s @@ -0,0 +1,68 @@ + .LEVEL 1.1 + +curframesz .EQU 128 +; SharedStub has stack size of 128 bytes + +lastframesz .EQU 64 +; the StubN C++ function has a small stack size of 64 bytes + + .SPACE $TEXT$,SORT=8 + .SUBSPA $CODE$,QUAD=0,ALIGN=4,ACCESS=0x2c,CODE_ONLY,SORT=24 +SharedStub + .PROC + .CALLINFO CALLER,FRAME=80,SAVE_RP,ARGS_SAVED + + .ENTRY + STW %rp,-20(%sp) + LDO 128(%sp),%sp + + STW %r19,-32(%r30) + STW %r26,-36-curframesz(%r30) ; save arg0 in previous frame + + LDO -80(%r30),%r28 + FSTD,MA %fr5,8(%r28) ; save darg0 + FSTD,MA %fr7,8(%r28) ; save darg1 + FSTW,MA %fr4L,4(%r28) ; save farg0 + FSTW,MA %fr5L,4(%r28) ; save farg1 + FSTW,MA %fr6L,4(%r28) ; save farg2 + FSTW,MA %fr7L,4(%r28) ; save farg3 + + ; Former value of register 26 is already properly saved by StubN, + ; but register 25-23 are not because of the arguments mismatch + STW %r25,-40-curframesz-lastframesz(%r30) ; save r25 + STW %r24,-44-curframesz-lastframesz(%r30) ; save r24 + STW %r23,-48-curframesz-lastframesz(%r30) ; save r23 + COPY %r26,%r25 ; method index is arg1 + LDW -36-curframesz-lastframesz(%r30),%r26 ; self is arg0 + LDO -40-curframesz-lastframesz(%r30),%r24 ; normal args is arg2 + LDO -80(%r30),%r23 ; floating args is arg3 + + BL .+8,%r2 + ADDIL L'PrepareAndDispatch-$PIC_pcrel$0+4,%r2 + LDO R'PrepareAndDispatch-$PIC_pcrel$1+8(%r1),%r1 +$PIC_pcrel$0 + LDSID (%r1),%r31 +$PIC_pcrel$1 + MTSP %r31,%sr0 + .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR,RTNVAL=GR +;in=23-26;out=28; + BLE 0(%sr0,%r1) + COPY %r31,%r2 + + LDW -32(%r30),%r19 + + LDW -148(%sp),%rp + BVE (%rp) + .EXIT + LDO -128(%sp),%sp + + + .PROCEND ;in=26;out=28; + + .ALIGN 8 + .SPACE $TEXT$ + .SUBSPA $CODE$ + .IMPORT PrepareAndDispatch,CODE + .EXPORT SharedStub,ENTRY,PRIV_LEV=3,ARGW0=GR,RTNVAL=GR,LONG_RETURN + .END + diff --git a/mozilla/xpcom/reflect/xptcall/src/md/unix/xptcstubs_pa32.cpp b/mozilla/xpcom/reflect/xptcall/src/md/unix/xptcstubs_pa32.cpp new file mode 100644 index 00000000000..41076bf2ccb --- /dev/null +++ b/mozilla/xpcom/reflect/xptcall/src/md/unix/xptcstubs_pa32.cpp @@ -0,0 +1,156 @@ + +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1999 Netscape Communications Corporation. All Rights + * Reserved. + */ + +/* Implement shared vtbl methods. */ + +#include "xptcprivate.h" + +#if _HPUX +#error "This code is for HP-PA RISC 32 bit mode only" +#endif + +extern "C" nsresult +PrepareAndDispatch(nsXPTCStubBase* self, PRUint32 methodIndex, + PRUint32* args, PRUint32* floatargs) +{ + + typedef struct { + uint32 hi; + uint32 lo; + } DU; + +#define PARAM_BUFFER_COUNT 16 + + nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT]; + nsXPTCMiniVariant* dispatchParams = NULL; + nsIInterfaceInfo* iface_info = NULL; + const nsXPTMethodInfo* info; + PRInt32 regwords = 1; /* self pointer is not in the variant records */ + nsresult result = NS_ERROR_FAILURE; + PRUint8 paramCount; + PRUint8 i; + + 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"); + + for(i = 0; i < paramCount; ++i, --args) + { + const nsXPTParamInfo& param = info->GetParam(i); + const nsXPTType& type = param.GetType(); + nsXPTCMiniVariant* dp = &dispatchParams[i]; + + if(param.IsOut() || !type.IsArithmetic()) + { + dp->val.p = (void*) *args; + ++regwords; + continue; + } + switch(type) + { + case nsXPTType::T_I8 : dp->val.i8 = *((PRInt32*) args); break; + case nsXPTType::T_I16 : dp->val.i16 = *((PRInt32*) args); break; + case nsXPTType::T_I32 : dp->val.i32 = *((PRInt32*) args); break; + case nsXPTType::T_DOUBLE : + if (regwords & 1) + { + ++regwords; /* align on double word */ + --args; + } + if (regwords == 0 || regwords == 2) + { + dp->val.d=*((double*) (floatargs + regwords)); + --args; + } + else + { + dp->val.d = *((double*) --args); + } + regwords += 2; + continue; + case nsXPTType::T_U64 : + case nsXPTType::T_I64 : + if (regwords & 1) + { + ++regwords; /* align on double word */ + --args; + } + ((DU *)dp)->lo = *((PRUint32*) args); + ((DU *)dp)->hi = *((PRUint32*) --args); + regwords += 2; + continue; + case nsXPTType::T_FLOAT : + if (regwords >= 4) + dp->val.f = *((float*) args); + else + dp->val.f = *((float*) floatargs+4+regwords); + break; + case nsXPTType::T_U8 : dp->val.u8 = *((PRUint32*) args); break; + case nsXPTType::T_U16 : dp->val.u16 = *((PRUint32*) args); break; + case nsXPTType::T_U32 : dp->val.u32 = *((PRUint32*) args); break; + case nsXPTType::T_BOOL : dp->val.b = *((PRBool*) args); break; + case nsXPTType::T_CHAR : dp->val.c = *((PRUint32*) args); break; + case nsXPTType::T_WCHAR : dp->val.wc = *((PRInt32*) args); break; + default: + NS_ASSERTION(0, "bad type"); + break; + } + ++regwords; + } + + result = self->CallMethod((PRUint16) methodIndex, info, dispatchParams); + + NS_RELEASE(iface_info); + + if(dispatchParams != paramBuffer) + delete [] dispatchParams; + + return result; +} + +extern "C" int SharedStub(int); + +#define STUB_ENTRY(n) \ +nsresult nsXPTCStubBase::Stub##n() \ +{ \ + return SharedStub(n); \ +} + +#define SENTINEL_ENTRY(n) \ +nsresult nsXPTCStubBase::Sentinel##n() \ +{ \ + NS_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \ + return NS_ERROR_NOT_IMPLEMENTED; \ +} + +#include "xptcstubsdef.inc" +