Back to index

lightning-sunbird  0.9+nobinonly
xptcinvoke_pa32.cpp
Go to the documentation of this file.
00001 
00002 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
00003  *
00004  * ***** BEGIN LICENSE BLOCK *****
00005  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00006  *
00007  * The contents of this file are subject to the Mozilla Public License Version
00008  * 1.1 (the "License"); you may not use this file except in compliance with
00009  * the License. You may obtain a copy of the License at
00010  * http://www.mozilla.org/MPL/
00011  *
00012  * Software distributed under the License is distributed on an "AS IS" basis,
00013  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00014  * for the specific language governing rights and limitations under the
00015  * License.
00016  *
00017  * The Original Code is mozilla.org code.
00018  *
00019  * The Initial Developer of the Original Code is
00020  * Netscape Communications Corporation.
00021  * Portions created by the Initial Developer are Copyright (C) 1999
00022  * the Initial Developer. All Rights Reserved.
00023  *
00024  * Contributor(s):
00025  *
00026  * Alternatively, the contents of this file may be used under the terms of
00027  * either of the GNU General Public License Version 2 or later (the "GPL"),
00028  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00029  * in which case the provisions of the GPL or the LGPL are applicable instead
00030  * of those above. If you wish to allow use of your version of this file only
00031  * under the terms of either the GPL or the LGPL, and not to allow others to
00032  * use your version of this file under the terms of the MPL, indicate your
00033  * decision by deleting the provisions above and replace them with the notice
00034  * and other provisions required by the GPL or the LGPL. If you do not delete
00035  * the provisions above, a recipient may use your version of this file under
00036  * the terms of any one of the MPL, the GPL or the LGPL.
00037  *
00038  * ***** END LICENSE BLOCK ***** */
00039 
00040 #include "xptcprivate.h"
00041 
00042 #if _HPUX
00043 #error "This code is for HP-PA RISC 32 bit mode only"
00044 #endif
00045 
00046 #include <alloca.h>
00047 
00048 typedef unsigned nsXPCVariant;
00049 
00050 extern "C" PRInt32
00051 invoke_count_bytes(nsISupports* that, const PRUint32 methodIndex,
00052   const PRUint32 paramCount, const nsXPTCVariant* s)
00053 {
00054   PRInt32 result = 4; /* variant records do not include self pointer */
00055 
00056   /* counts the number of bytes required by the argument stack,
00057      64 bit integer, and double requires 8 bytes.  All else requires
00058      4 bytes.
00059    */
00060 
00061   {
00062     PRUint32 indx;
00063     for (indx = paramCount; indx > 0; --indx, ++s)
00064     {
00065       if (! s->IsPtrData())
00066       {
00067         if (s->type == nsXPTType::T_I64 || s->type == nsXPTType::T_U64 ||
00068             s->type == nsXPTType::T_DOUBLE)
00069         {
00070           /* 64 bit integer and double aligned on 8 byte boundaries */
00071           result += (result & 4) + 8;
00072           continue;
00073         }
00074       }
00075       result += 4; /* all other cases use 4 bytes */
00076     }
00077   }
00078   result -= 72; /* existing stack buffer is 72 bytes */
00079   if (result < 0)
00080     return 0;
00081   {
00082     /* round up to 64 bytes boundary */
00083     PRInt32 remainder = result & 63;
00084     return (remainder == 0) ? result : (result + 64 - remainder);
00085   }
00086 }
00087 
00088 extern "C" PRUint32
00089 invoke_copy_to_stack(PRUint32* d,
00090   const PRUint32 paramCount, nsXPTCVariant* s)
00091 {
00092 
00093   typedef struct
00094   {
00095     PRUint32 hi;
00096     PRUint32 lo;
00097   } DU;
00098 
00099   PRUint32* dest = d;
00100   nsXPTCVariant* source = s;
00101   /* we clobber param vars by copying stuff on stack, have to use local var */
00102 
00103   PRUint32 floatflags = 0;
00104   /* flag indicating which floating point registers to load */
00105 
00106   PRUint32 regwords = 1; /* register 26 is reserved for ptr to 'that' */
00107   PRUint32 indx;
00108 
00109   for (indx = paramCount; indx > 0; --indx, --dest, ++source)
00110   {
00111     if (source->IsPtrData())
00112     {
00113       *((void**) dest) = source->ptr;
00114       ++regwords;
00115       continue;
00116     }
00117     switch (source->type)
00118     {
00119     case nsXPTType::T_I8    : *((PRInt32*) dest) = source->val.i8;  break;
00120     case nsXPTType::T_I16   : *((PRInt32*) dest) = source->val.i16; break;
00121     case nsXPTType::T_I32   : *((PRInt32*) dest) = source->val.i32; break;
00122     case nsXPTType::T_I64   :
00123     case nsXPTType::T_U64   :
00124       if (regwords & 1)
00125       {
00126         /* align on double word boundary */
00127         --dest;
00128         ++regwords;
00129       }
00130       *((uint32*) dest) = ((DU *) source)->lo;
00131       *((uint32*) --dest) = ((DU *) source)->hi;
00132       /* big endian - hi word in low addr */
00133       regwords += 2;
00134       continue;
00135     case nsXPTType::T_DOUBLE :
00136       if (regwords & 1)
00137       {
00138         /* align on double word boundary */
00139         --dest;
00140         ++regwords;
00141       }
00142       switch (regwords) /* load double precision float register */
00143       {
00144       case 2:
00145         floatflags |= 1;
00146       }
00147       *((uint32*) dest) = ((DU *) source)->lo;
00148       *((uint32*) --dest) = ((DU *) source)->hi;
00149       /* big endian - hi word in low addr */
00150       regwords += 2;
00151       continue;
00152     case nsXPTType::T_FLOAT :
00153       switch (regwords) /* load single precision float register */
00154       {
00155       case 1:
00156         floatflags |= 2;
00157         break;
00158       case 2:
00159         floatflags |= 4;
00160         break;
00161       case 3:
00162         floatflags |= 8;
00163       }
00164       *((float*) dest) = source->val.f;
00165       break;
00166     case nsXPTType::T_U8    : *((PRUint32*) (dest)) = source->val.u8; break;
00167     case nsXPTType::T_U16   : *((PRUint32*) (dest)) = source->val.u16; break;
00168     case nsXPTType::T_U32   : *((PRUint32*) (dest)) = source->val.u32; break;
00169     case nsXPTType::T_BOOL  : *((PRBool*)   (dest)) = source->val.b; break;
00170     case nsXPTType::T_CHAR  : *((PRUint32*) (dest)) = source->val.c; break;
00171     case nsXPTType::T_WCHAR : *((PRInt32*)  (dest)) = source->val.wc; break;
00172 
00173     default:
00174       // all the others are plain pointer types
00175       *((void**) dest) = source->val.p;
00176     }
00177     ++regwords;
00178   }
00179   return floatflags;
00180 }
00181