Back to index

lightning-sunbird  0.9+nobinonly
xptcinvoke_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) 1998
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 /* Platform specific code to invoke XPCOM methods on native objects */
00039 
00040 /* contributed by Glen Nakamura <glen.nakamura@usa.net> */
00041 
00042 #include "xptcprivate.h"
00043 
00044 /* Prototype specifies unmangled function name and disables unused warning */
00045 static void
00046 invoke_copy_to_stack(PRUint64* d, PRUint32 paramCount, nsXPTCVariant* s)
00047 __asm__("invoke_copy_to_stack") __attribute__((unused));
00048 
00049 static void
00050 invoke_copy_to_stack(PRUint64* d, PRUint32 paramCount, nsXPTCVariant* s)
00051 {
00052     const PRUint8 NUM_ARG_REGS = 6-1;        // -1 for "this" pointer
00053 
00054     for(PRUint32 i = 0; i < paramCount; i++, d++, s++)
00055     {
00056         if(s->IsPtrData())
00057         {
00058             *d = (PRUint64)s->ptr;
00059             continue;
00060         }
00061         switch(s->type)
00062         {
00063         case nsXPTType::T_I8     : *d = (PRUint64)s->val.i8;     break;
00064         case nsXPTType::T_I16    : *d = (PRUint64)s->val.i16;    break;
00065         case nsXPTType::T_I32    : *d = (PRUint64)s->val.i32;    break;
00066         case nsXPTType::T_I64    : *d = (PRUint64)s->val.i64;    break;
00067         case nsXPTType::T_U8     : *d = (PRUint64)s->val.u8;     break;
00068         case nsXPTType::T_U16    : *d = (PRUint64)s->val.u16;    break;
00069         case nsXPTType::T_U32    : *d = (PRUint64)s->val.u32;    break;
00070         case nsXPTType::T_U64    : *d = (PRUint64)s->val.u64;    break;
00071         case nsXPTType::T_FLOAT  :
00072             if(i < NUM_ARG_REGS)
00073             {
00074                 // convert floats to doubles if they are to be passed
00075                 // via registers so we can just deal with doubles later
00076                 union { PRUint64 u64; double d; } t;
00077                 t.d = (double)s->val.f;
00078                 *d = t.u64;
00079             }
00080             else
00081                 // otherwise copy to stack normally
00082                 *d = (PRUint64)s->val.u32;
00083             break;
00084         case nsXPTType::T_DOUBLE : *d = (PRUint64)s->val.u64;    break;
00085         case nsXPTType::T_BOOL   : *d = (PRUint64)s->val.b;      break;
00086         case nsXPTType::T_CHAR   : *d = (PRUint64)s->val.c;      break;
00087         case nsXPTType::T_WCHAR  : *d = (PRUint64)s->val.wc;     break;
00088         default:
00089             // all the others are plain pointer types
00090             *d = (PRUint64)s->val.p;
00091             break;
00092         }
00093     }
00094 }
00095 
00096 /*
00097  * XPTC_PUBLIC_API(nsresult)
00098  * XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex,
00099  *                    PRUint32 paramCount, nsXPTCVariant* params, void* vt)
00100  */
00101 __asm__(
00102     "#### XPTC_InvokeByIndex ####\n"
00103 ".text\n\t"
00104     ".align 5\n\t"
00105     ".globl XPTC_InvokeByIndex\n\t"
00106     ".ent XPTC_InvokeByIndex\n"
00107 "XPTC_InvokeByIndex:\n\t"
00108     ".frame $15,32,$26,0\n\t"
00109     ".mask 0x4008000,-32\n\t"
00110     "ldgp $29,0($27)\n"
00111 "$XPTC_InvokeByIndex..ng:\n\t"
00112     "subq $30,32,$30\n\t"
00113     "stq $26,0($30)\n\t"
00114     "stq $15,8($30)\n\t"
00115     "bis $30,$30,$15\n\t"
00116     ".prologue 1\n\t"
00117 
00118     /*
00119      * Allocate enough stack space to hold the greater of 6 or "paramCount"+1
00120      * parameters. (+1 for "this" pointer)  Room for at least 6 parameters
00121      * is required for storage of those passed via registers.
00122      */
00123 
00124     "bis $31,5,$2\n\t"      /* count = MAX(5, "paramCount") */
00125     "cmplt $2,$18,$1\n\t"
00126     "cmovne $1,$18,$2\n\t"
00127     "s8addq $2,16,$1\n\t"   /* room for count+1 params (8 bytes each) */
00128     "bic $1,15,$1\n\t"      /* stack space is rounded up to 0 % 16 */
00129     "subq $30,$1,$30\n\t"
00130 
00131     "stq $16,0($30)\n\t"    /* save "that" (as "this" pointer) */
00132     "stq $17,16($15)\n\t"   /* save "methodIndex" */
00133 
00134     "addq $30,8,$16\n\t"    /* pass stack pointer */
00135     "bis $18,$18,$17\n\t"   /* pass "paramCount" */
00136     "bis $19,$19,$18\n\t"   /* pass "params" */
00137     "bsr $26,$invoke_copy_to_stack..ng\n\t"     /* call invoke_copy_to_stack */
00138 
00139     /*
00140      * Copy the first 6 parameters to registers and remove from stack frame.
00141      * Both the integer and floating point registers are set for each parameter
00142      * except the first which is the "this" pointer.  (integer only)
00143      * The floating point registers are all set as doubles since the
00144      * invoke_copy_to_stack function should have converted the floats.
00145      */
00146     "ldq $16,0($30)\n\t"    /* integer registers */
00147     "ldq $17,8($30)\n\t"
00148     "ldq $18,16($30)\n\t"
00149     "ldq $19,24($30)\n\t"
00150     "ldq $20,32($30)\n\t"
00151     "ldq $21,40($30)\n\t"
00152     "ldt $f17,8($30)\n\t"   /* floating point registers */
00153     "ldt $f18,16($30)\n\t"
00154     "ldt $f19,24($30)\n\t"
00155     "ldt $f20,32($30)\n\t"
00156     "ldt $f21,40($30)\n\t"
00157 
00158     "addq $30,48,$30\n\t"   /* remove params from stack */
00159 
00160     /*
00161      * Call the virtual function with the constructed stack frame.
00162      */
00163     "bis $16,$16,$1\n\t"    /* load "this" */
00164     "ldq $2,16($15)\n\t"    /* load "methodIndex" */
00165     "ldq $1,0($1)\n\t"      /* load vtable */
00166 #if 0
00167     "s8addq $2,16,$2\n\t"   /* vtable index = "methodIndex" * 8 + 16 */
00168 #else
00169     "mulq $2, 8, $2\n\t"
00170     "addq $2, 0, $2\n\t"   /* vtable index = "methodIndex" * 16 + 24 */
00171 #endif
00172     "addq $1,$2,$1\n\t"
00173     "ldq $27,0($1)\n\t"     /* load address of function */
00174     "jsr $26,($27),0\n\t"   /* call virtual function */
00175     "ldgp $29,0($26)\n\t"
00176 
00177     "bis $15,$15,$30\n\t"
00178     "ldq $26,0($30)\n\t"
00179     "ldq $15,8($30)\n\t"
00180     "addq $30,32,$30\n\t"
00181     "ret $31,($26),1\n\t"
00182     ".end XPTC_InvokeByIndex"
00183     );
00184