/* Copyright (c) Microsoft Corporation. All rights reserved. */
#include <arm_asm.h>

        _CODE(C$$code)
/*
 * ARM assembly source file for machine dependent RPC... stuff
 */
        _EXPORT(strump)
	_EXPORT(ProxyCommonTemplate)
	_EXPORT(ProxyCommonTemplateEnd)
	_EXPORT(ProxyTemplate)
	_EXPORT(ProxyTemplateEnd)
	_IMPORT(ProxyInterpreter)

/*
 * UINT strump(ADDRESS newsp, ADDRESS newpc)
 * 
 * Switches to a new stack and jumps to the RPC destination. Sets up 
 * in arguments before and out arguments after. Switches back to old 
 * stack.
 *
 * newsp (r0): Address of the new stack 
 * newpc (r1): The value of the new program counter (RPC destination)
 */
_FUNCTION(strump)
        stmdb   sp!,{r9-r10,lr} /* save register state on old stack */
        mov             r10,sp  /* save the old stack pointer */

        mov             sp,r0   /* switch to the new stack */
        mov             r9,r1   /* avoid clobbering the pc argument */

        ldmia   sp!,{r0-r3}     /* copy args to regs and pop off (new) stack*/ 

        mov             lr,pc   /* setup for returning after jump */
        mov             pc,r9   /* jump to new pc */

                                /* RPC return value now in r0 */
        
        mov             sp,r10  /* switch to the old stack */

        ldmia   sp!,{r9-r10,pc} /* restore registers and return */

/* Client side code that gets pointed to by proxy v-tables. See soapmd.s. */
_LABEL(ProxyCommonTemplate)
        stmdb sp!, {r0-r3}      /* Pass args on stack */
        stmdb sp!, {lr}         /* Save *below* args */
        mov r0, ip
        mov r1, sp
        ldr ip, _L(interp)      /* bl ProxyInterPreter, 32 bit version... */
        mov lr, pc
        mov pc, ip
        ldr ip, [sp], #+20  /* Pop the 5 words saved above: ip gets saved lr */
        mov pc, ip              /* return */
_LABEL(interp)
        _DCD ProxyInterpreter
_LABEL(ProxyCommonTemplateEnd)

_LABEL(ProxyTemplate)
        ldr ip, _L(descr)
        b _L(ProxyCommonTemplate)  /* pc relative, must be adjusted */
_LABEL(descr)
        _DCD 0                  /* gets filled in with method descriptor ptr */
_LABEL(ProxyTemplateEnd)
        _END