Back to index

lightning-sunbird  0.9+nobinonly
xptcstubs_openbsd_alpha.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: NPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Netscape Public License
00006  * Version 1.1 (the "License"); you may not use this file except in
00007  * compliance with the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/NPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is 
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1999
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or 
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the NPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the NPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 /* Implement shared vtbl methods. */
00039 
00040 /* contributed by Glen Nakamura <glen.nakamura@usa.net> */
00041 
00042 #include <sys/types.h>
00043 #include <machine/cpu.h>
00044 #include "xptcprivate.h"
00045 
00046 /* Prototype specifies unmangled function name and disables unused warning */
00047 static nsresult
00048 PrepareAndDispatch(nsXPTCStubBase* self, uint32 methodIndex, PRUint64* args)
00049 __asm__("PrepareAndDispatch") __attribute__((unused));
00050 
00051 static nsresult
00052 PrepareAndDispatch(nsXPTCStubBase* self, uint32 methodIndex, PRUint64* args)
00053 {
00054     const PRUint8 PARAM_BUFFER_COUNT = 16;
00055     const PRUint8 NUM_ARG_REGS = 6-1;        // -1 for "this" pointer
00056 
00057     nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
00058     nsXPTCMiniVariant* dispatchParams = NULL;
00059     nsIInterfaceInfo* iface_info = NULL;
00060     const nsXPTMethodInfo* info;
00061     PRUint8 paramCount;
00062     PRUint8 i;
00063     nsresult result = NS_ERROR_FAILURE;
00064 
00065     NS_ASSERTION(self,"no self");
00066 
00067     self->GetInterfaceInfo(&iface_info);
00068     NS_ASSERTION(iface_info,"no interface info");
00069 
00070     iface_info->GetMethodInfo(PRUint16(methodIndex), &info);
00071     NS_ASSERTION(info,"no interface info");
00072 
00073     paramCount = info->GetParamCount();
00074 
00075     // setup variant array pointer
00076     if(paramCount > PARAM_BUFFER_COUNT)
00077         dispatchParams = new nsXPTCMiniVariant[paramCount];
00078     else
00079         dispatchParams = paramBuffer;
00080     NS_ASSERTION(dispatchParams,"no place for params");
00081 
00082     // args[0] to args[NUM_ARG_REGS] hold floating point register values
00083     PRUint64* ap = args + NUM_ARG_REGS;
00084     for(i = 0; i < paramCount; i++, ap++)
00085     {
00086         const nsXPTParamInfo& param = info->GetParam(i);
00087         const nsXPTType& type = param.GetType();
00088         nsXPTCMiniVariant* dp = &dispatchParams[i];
00089 
00090         if(param.IsOut() || !type.IsArithmetic())
00091         {
00092             dp->val.p = (void*) *ap;
00093             continue;
00094         }
00095         // else
00096         switch(type)
00097         {
00098         case nsXPTType::T_I8     : dp->val.i8  = (PRInt8)    *ap;    break;
00099         case nsXPTType::T_I16    : dp->val.i16 = (PRInt16)   *ap;    break;
00100         case nsXPTType::T_I32    : dp->val.i32 = (PRInt32)   *ap;    break;
00101         case nsXPTType::T_I64    : dp->val.i64 = (PRInt64)   *ap;    break;
00102         case nsXPTType::T_U8     : dp->val.u8  = (PRUint8)   *ap;    break;
00103         case nsXPTType::T_U16    : dp->val.u16 = (PRUint16)  *ap;    break;
00104         case nsXPTType::T_U32    : dp->val.u32 = (PRUint32)  *ap;    break;
00105         case nsXPTType::T_U64    : dp->val.u64 = (PRUint64)  *ap;    break;
00106         case nsXPTType::T_FLOAT  :
00107             if(i < NUM_ARG_REGS)
00108             {
00109                 // floats passed via registers are stored as doubles
00110                 // in the first NUM_ARG_REGS entries in args
00111                 dp->val.u64 = (PRUint64) args[i];
00112                 dp->val.f = (float) dp->val.d;    // convert double to float
00113             }
00114             else
00115                 dp->val.u32 = (PRUint32) *ap;
00116             break;
00117         case nsXPTType::T_DOUBLE :
00118             // doubles passed via registers are also stored
00119             // in the first NUM_ARG_REGS entries in args
00120             dp->val.u64 = (i < NUM_ARG_REGS) ? args[i] : *ap;
00121             break;
00122         case nsXPTType::T_BOOL   : dp->val.b   = (PRBool)    *ap;    break;
00123         case nsXPTType::T_CHAR   : dp->val.c   = (char)      *ap;    break;
00124         case nsXPTType::T_WCHAR  : dp->val.wc  = (PRUnichar) *ap;    break;
00125         default:
00126             NS_ASSERTION(0, "bad type");
00127             break;
00128         }
00129     }
00130 
00131     result = self->CallMethod((PRUint16)methodIndex, info, dispatchParams);
00132 
00133     NS_RELEASE(iface_info);
00134 
00135     if(dispatchParams != paramBuffer)
00136         delete [] dispatchParams;
00137 
00138     return result;
00139 }
00140 
00141 /*
00142  * SharedStub()
00143  *  Collects arguments and calls PrepareAndDispatch.  The "methodIndex" is
00144  *  passed to this function via $1 to preserve the argument registers.
00145  */
00146 __asm__(
00147     "#### SharedStub ####\n"
00148 ".text\n\t"
00149     ".align 5\n\t"
00150     ".ent SharedStub\n"
00151 "SharedStub:\n\t"
00152     ".frame $30,96,$26,0\n\t"
00153     ".mask 0x4000000,-96\n\t"
00154     "ldgp $29,0($27)\n"
00155 "$SharedStub..ng:\n\t"
00156     "subq $30,96,$30\n\t"
00157     "stq $26,0($30)\n\t"
00158     ".prologue 1\n\t"
00159 
00160     /*
00161      * Store arguments passed via registers to the stack.
00162      * Floating point registers are stored as doubles and converted
00163      * to floats in PrepareAndDispatch if necessary.
00164      */
00165     "stt $f17,16($30)\n\t"   /* floating point registers */
00166     "stt $f18,24($30)\n\t"
00167     "stt $f19,32($30)\n\t"
00168     "stt $f20,40($30)\n\t"
00169     "stt $f21,48($30)\n\t"
00170     "stq $17,56($30)\n\t"    /* integer registers */
00171     "stq $18,64($30)\n\t"
00172     "stq $19,72($30)\n\t"
00173     "stq $20,80($30)\n\t"
00174     "stq $21,88($30)\n\t"
00175 
00176     /*
00177      * Call PrepareAndDispatch function.
00178      */
00179     "bis $1,$1,$17\n\t"      /* pass "methodIndex" */
00180     "addq $30,16,$18\n\t"    /* pass "args" */
00181     "bsr $26,$PrepareAndDispatch..ng\n\t"
00182 
00183     "ldq $26,0($30)\n\t"
00184     "addq $30,96,$30\n\t"
00185     "ret $31,($26),1\n\t"
00186     ".end SharedStub"
00187     );
00188 
00189 #if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100 /* G++ V3 ABI */
00190 /*
00191  * nsresult nsXPTCStubBase::Stub##n()
00192  *  Sets register $1 to "methodIndex" and jumps to SharedStub.
00193  */
00194 #define STUB_ENTRY(n) \
00195 __asm__( \
00196     "#### Stub"#n" ####\n" \
00197 ".text\n\t" \
00198     ".align 5\n\t" \
00199     ".globl _ZN14nsXPTCStubBase5Stub"#n"Ev\n\t" \
00200     ".ent _ZN14nsXPTCStubBase5Stub"#n"Ev\n" \
00201 "_ZN14nsXPTCStubBase5Stub"#n"Ev:\n\t" \
00202     ".frame $30,0,$26,0\n\t" \
00203     "ldgp $29,0($27)\n" \
00204 "$_ZN14nsXPTCStubBase5Stub"#n"Ev..ng:\n\t" \
00205     ".prologue 1\n\t" \
00206     "lda $1,"#n"\n\t" \
00207     "br $31,$SharedStub..ng\n\t" \
00208     ".end _ZN14nsXPTCStubBase5Stub"#n"Ev" \
00209     ); \
00210 __asm__( \
00211     "#### Stub"#n" ####\n" \
00212 ".text\n\t" \
00213     ".align 5\n\t" \
00214     ".globl _ZN14nsXPTCStubBase6Stub"#n"Ev\n\t" \
00215     ".ent _ZN14nsXPTCStubBase6Stub"#n"Ev\n" \
00216 "_ZN14nsXPTCStubBase6Stub"#n"Ev:\n\t" \
00217     ".frame $30,0,$26,0\n\t" \
00218     "ldgp $29,0($27)\n" \
00219 "$_ZN14nsXPTCStubBase6Stub"#n"Ev..ng:\n\t" \
00220     ".prologue 1\n\t" \
00221     "lda $1,"#n"\n\t" \
00222     "br $31,$SharedStub..ng\n\t" \
00223     ".end _ZN14nsXPTCStubBase6Stub"#n"Ev" \
00224     ); \
00225 __asm__( \
00226     "#### Stub"#n" ####\n" \
00227 ".text\n\t" \
00228     ".align 5\n\t" \
00229     ".globl _ZN14nsXPTCStubBase7Stub"#n"Ev\n\t" \
00230     ".ent _ZN14nsXPTCStubBase7Stub"#n"Ev\n" \
00231 "_ZN14nsXPTCStubBase7Stub"#n"Ev:\n\t" \
00232     ".frame $30,0,$26,0\n\t" \
00233     "ldgp $29,0($27)\n" \
00234 "$_ZN14nsXPTCStubBase7Stub"#n"Ev..ng:\n\t" \
00235     ".prologue 1\n\t" \
00236     "lda $1,"#n"\n\t" \
00237     "br $31,$SharedStub..ng\n\t" \
00238     ".end _ZN14nsXPTCStubBase7Stub"#n"Ev" \
00239     );
00240 #else
00241 /*
00242  * nsresult nsXPTCStubBase::Stub##n()
00243  *  Sets register $1 to "methodIndex" and jumps to SharedStub.
00244  */
00245 #define STUB_ENTRY(n) \
00246 nsresult nsXPTCStubBase::Stub##n() \
00247 { \
00248     nsresult result; \
00249 __asm__ __volatile__( \
00250     "ldah    $29,0($27)\n\t" \
00251     "lda     $29,0($29)\n\t" \
00252     "lda $1, "#n"\n\t" \
00253     "br $31, $SharedStub..ng\n\t" \
00254     "mov $0, %0\n\t" \
00255     : "=r" (result) \
00256     ); \
00257     return result; \
00258 }
00259 #endif
00260 
00261 #define SENTINEL_ENTRY(n) \
00262 nsresult nsXPTCStubBase::Sentinel##n() \
00263 { \
00264     NS_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \
00265     return NS_ERROR_NOT_IMPLEMENTED; \
00266 }
00267 
00268 #include "xptcstubsdef.inc"
00269