2 // Copyright (c) 2006, Intel Corporation
3 // All rights reserved. This program and the accompanying materials
4 // are licensed and made available under the terms and conditions of the BSD License
5 // which accompanies this distribution. The full text of the license may be found at
6 // http://opensource.org/licenses/bsd-license.php
8 // THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
9 // WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 // Contains low level routines for the Virtual Machine implementation
18 // on an Itanium-based platform.
25 #define PROCEDURE_ENTRY(name) .##text; \
26 .##type name, @function; \
30 #define PROCEDURE_EXIT(name) .##endp name
32 // Note: use of NESTED_SETUP requires number of locals (l) >= 3
34 #define NESTED_SETUP(i,l,o,r) \
35 alloc loc1=ar##.##pfs,i,l,o,r ;\
38 #define NESTED_RETURN \
40 mov ar##.##pfs=loc1 ;;\
41 br##.##ret##.##dpnt b0;;
44 //-----------------------------------------------------------------------------
48 // Implements the low level EBC CALLEX instruction. Sets up the
49 // stack pointer, does the spill of function arguments, and
50 // calls the native function. On return it restores the original
51 // stack pointer and returns to the caller.
56 // in0 = Address of native code to call
57 // in1 = New stack pointer
61 // As per static calling conventions.
64 //---------------------------------------------------------------------------
65 ;// void EbcAsmLLCALLEX (UINTN FunctionAddr, UINTN EbcStackPointer)
66 PROCEDURE_ENTRY(EbcAsmLLCALLEX)
67 NESTED_SETUP (2,6,8,0)
69 // NESTED_SETUP uses loc0 and loc1 for context save
72 // Save a copy of the EBC VM stack pointer
77 // Copy stack arguments from EBC stack into registers.
78 // Assume worst case and copy 8.
90 // Save the original stack pointer
100 // Set the new aligned stack pointer. Reserve space for the required
101 // 16-bytes of scratch area as well.
106 // Now call the function. Load up the function address from the descriptor
107 // pointed to by in0. Then get the gp from the descriptor at the following
108 // address in the descriptor.
114 (p0) br.call.dptk.many b0 = b1;;
117 // Restore the original stack pointer and gp
127 PROCEDURE_EXIT(EbcAsmLLCALLEX)
130 // UINTN EbcLLGetEbcEntryPoint(VOID)
133 // Simply return, so that the caller retrieves the return register
134 // contents (R8). That's where the thunk-to-ebc code stuffed the
137 PROCEDURE_ENTRY(EbcLLGetEbcEntryPoint)
139 PROCEDURE_EXIT(EbcLLGetEbcEntryPoint)
142 // INT64 EbcLLGetReturnValue(VOID)
145 // This function is called to get the value returned by native code
146 // to EBC. It simply returns because the return value should still
147 // be in the register, so the caller just gets the unmodified value.
149 PROCEDURE_ENTRY(EbcLLGetReturnValue)
151 PROCEDURE_EXIT(EbcLLGetReturnValue)
154 // UINTN EbcLLGetStackPointer(VOID)
156 PROCEDURE_ENTRY(EbcLLGetStackPointer)
160 PROCEDURE_EXIT(EbcLLGetStackPointer)