Back to index

lightning-sunbird  0.9+nobinonly
Functions | Variables
xptcinvoke_nto_shle.cpp File Reference
#include "xptcprivate.h"

Go to the source code of this file.

Functions

static void copy_to_stack (PRUint32 paramCount, nsXPTCVariant *s, int size, PRUint32 *data)
 XPTC_InvokeByIndex (nsISupports *that, PRUint32 methodIndex, PRUint32 paramCount, nsXPTCVariant *params)

Variables

const int c_int_register_params = 3
const int c_float_register_params = 8

Function Documentation

static void copy_to_stack ( PRUint32  paramCount,
nsXPTCVariant s,
int  size,
PRUint32 data 
) [static]

Definition at line 9 of file xptcinvoke_nto_shle.cpp.

{
       int intCount = 0;
       int floatCount = 0;
       PRUint32 *intRegParams = data + (size / sizeof(PRUint32)) - c_int_register_params;
       float  *floatRegParams = (float *)intRegParams - c_float_register_params;

    for ( PRUint32 i = 0; i < paramCount; ++i, ++s )
    {
              nsXPTType type = s->IsPtrData() ? nsXPTType::T_I32 : s->type;

              switch ( type ) {
        case nsXPTType::T_I64:
        case nsXPTType::T_U64:
                     // Space to pass in registers?
                     if ( (c_int_register_params - intCount) >= 2 ) {
                            *((PRInt64 *) intRegParams) = s->val.i64;
                            intRegParams += 2;
                            intCount += 2;
                     }
                     else {
                            *((PRInt64*) data) = s->val.i64;
                            data += 2;
                     }
                     break;
        case nsXPTType::T_FLOAT:
                     // Space to pass in registers?
                     if ( floatCount < c_float_register_params ) {
                            *floatRegParams = s->val.f;
                            ++floatCount;
                            ++floatRegParams;
                     }
                     else {
                            *((float*) data) = s->val.f;
                            ++data;
                     }                    
                     break;
        case nsXPTType::T_DOUBLE:
                     // Space to pass in registers?
                     if ( (c_float_register_params - floatCount) >= 2  ) {
                            if ( (floatCount & 1) != 0 ) {
                                   ++floatCount;
                                   ++floatRegParams;                                
                            }
                            *(double *)floatRegParams = s->val.d;
                            floatCount += 2;
                            floatRegParams += 2;
                     }
                     else {
                            *((double *) data) = s->val.d;
                            data += 2;
                     }                    
                     break;
              default:             // 32 (non-float) value
                     PRInt32 value = (PRInt32) (s->IsPtrData() ?  s->ptr : s->val.p);
                     // Space to pass in registers?
                     if ( intCount < c_int_register_params ) {
                            *intRegParams = value;
                            ++intRegParams;
                            ++intCount;
                     }
                     else {
                            *data = value;
                            ++data;
                     }
                     break;
        }
    }  
}

Here is the call graph for this function:

Here is the caller graph for this function:

XPTC_InvokeByIndex ( nsISupports *  that,
PRUint32  methodIndex,
PRUint32  paramCount,
nsXPTCVariant params 
)

Definition at line 80 of file xptcinvoke_nto_shle.cpp.

{
#ifdef __GNUC__            /* Gnu compiler. */
       int result;
       void (*fn_copy) (PRUint32 paramCount, nsXPTCVariant* s, int size, PRUint32* d) = copy_to_stack;

       /* Because the SH processor passes the first few parameters in registers
          it is a bit tricky setting things up right.  To make things easier,
          all the hard work will be done by copy_to_stack above.  We pass to it
          a chunk of memory, the top of which will be copied to registers r5 to r7
          and fr4 to fr11 before calling the target function.
       */

 __asm__ __volatile__(
    /* Make space for parameters to be passed to the method.  Assume worst case 
          8 bytes per parameter.  Also leave space for 3 longs and 8 floats that
          will be put into registers.  The worst case is all int64 parameters
          and even in this case 8 bytes are passed in registers so we can
          deduct this from our allocation.
       */
       "mov.l @(8,r14), r4 \n\t"   // copy_to_stack paramCount parameter
       "mov   r4, r6 \n\t"
       "mov   #3, r1 \n\t"
       "shld  r1, r6 \n\t"
       "add   #36, r6 \n\t"        // Space for 3 longs, 8 floats - 8 bytes
       "sub   r6, r15 \n\t"
       "mov   r15, r7 \n\t"
       "mov.l @(20,r14), r1 \n\t"  // fn_copy
       "jsr   @r1 \n\t"                   // Note, next instruction is executed first
       "mov.l @(12,r14), r5 \n\t"  // copy_to_stack data parameter

       /* Now everything is laid out nicely in the stack.  We just have to
          load values at the top end of the memory area into registers and
          make the call.  We may load more things into registers than needed,
          but nobody will care about that.
       */     
       "mov   r14, r1 \n\t"
       "add   #-44, r1 \n\t"
       "fmov.s       @r1+, fr5 \n\t"
       "fmov.s       @r1+, fr4 \n\t"
       "fmov.s       @r1+, fr7 \n\t"
       "fmov.s       @r1+, fr6 \n\t"
       "fmov.s       @r1+, fr9 \n\t"
       "fmov.s       @r1+, fr8 \n\t"
       "fmov.s       @r1+, fr11 \n\t"
       "fmov.s       @r1+, fr10 \n\t"
       "mov.l @r1+, r5 \n\t"
       "mov.l @r1+, r6 \n\t"
       "mov.l @r1+, r7 \n\t"       
       "mov.l @r14, r1 \n\t"              // that -> r1
       "mov.l @r1, r1 \n\t"        // vtbl -> r1
       "mov.l @(4,r14), r4 \n\t"   // methodIndex -> r4
       "shll2 r4     \n\t"
       "add   r4, r1 \n\t"
       "mov.l @r1, r1 \n\t"        // method addr -> r1
       "jsr   @r1 \n\t"
       "mov.l @r14, r4 \n\t"              // that -> r4  (note, executed before jsr)
       "mov.l r0, @(16,r14) \n\r"  // Save return value in result
    : : : "r1", "r4", "r6", "r7", "pr", "dr4", "dr6", "dr8"
   );
    
  return result;

#else
#error "can't find a compiler to use"
#endif /* __GNUC__ */

}

Here is the call graph for this function:


Variable Documentation

Definition at line 6 of file xptcinvoke_nto_shle.cpp.

Definition at line 5 of file xptcinvoke_nto_shle.cpp.