EbcLowLevel.s revision 4fd606d1f5abe38e1f42c38de1d2e895166bd0f4
///** @file
//
// Contains low level routines for the Virtual Machine implementation
// on an Itanium-based platform.
//
// Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
// This program and the accompanying materials
// are licensed and made available under the terms and conditions of the BSD License
// which accompanies this distribution. The full text of the license may be found at
//
// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
//
//**/
name::
// Note: use of NESTED_SETUP requires number of locals (l) >= 3
#define NESTED_SETUP(i,l,o,r) \
#define NESTED_RETURN \
//-----------------------------------------------------------------------------
//++
// EbcAsmLLCALLEX
//
// Implements the low level EBC CALLEX instruction. Sets up the
// stack pointer, does the spill of function arguments, and
// calls the native function. On return it restores the original
// stack pointer and returns to the caller.
//
// Arguments :
//
// On Entry :
// in0 = Address of native code to call
// in1 = New stack pointer
//
// Return Value:
//
// As per static calling conventions.
//
//--
//---------------------------------------------------------------------------
;// void EbcAsmLLCALLEX (UINTN FunctionAddr, UINTN EbcStackPointer)
// NESTED_SETUP uses loc0 and loc1 for context save
//
// Save a copy of the EBC VM stack pointer
//
//
// Copy stack arguments from EBC stack into registers.
// Assume worst case and copy 8.
//
//
// Save the original stack pointer
//
//
// Save the gp
//
//
// Set the new aligned stack pointer. Reserve space for the required
// 16-bytes of scratch area as well.
//
//
// Now call the function. Load up the function address from the descriptor
// pointed to by in0. Then get the gp from the descriptor at the following
// address in the descriptor.
//
//
// Restore the original stack pointer and gp
//
//
// Now return
//
//-----------------------------------------------------------------------------
//++
// EbcLLCALLEXNative
//
// This function is called to execute an EBC CALLEX instruction.
// This instruction requires that we thunk out to external native
// code. On return, we restore the stack pointer to its original location.
// Destroys no working registers. For IPF, at least 8 register slots
// must be allocated on the stack frame to support any number of
// arguments beiung passed to the external native function. The
// size of the stack frame is FramePtr - EbcSp. If this size is less
// than 64-bytes, the amount of stack frame allocated is rounded up
// to 64-bytes
//
// Arguments On Entry :
// in0 = CallAddr The function address.
// in1 = EbcSp The new EBC stack pointer.
// in2 = FramePtr The frame pointer.
//
// Return Value:
// None
//
// C Function Prototype:
// VOID
// EFIAPI
// EbcLLCALLEXNative (
// IN UINTN CallAddr,
// IN UINTN EbcSp,
// IN VOID *FramePtr
// );
//--
//---------------------------------------------------------------------------
cmp.leu p6 = out2, loc4;; // IF out2 < loc4 THEN P6=1 ELSE P6=0; IF (FramePtr - EbcSp) < 0x40 THEN P6 = 1 ELSE P6=0
//
// UINTN EbcLLGetEbcEntryPoint(VOID)
//
// Description:
// Simply return, so that the caller retrieves the return register
// contents (R8). That's where the thunk-to-ebc code stuffed the
// EBC entry point.
//