]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/EbcDxe/Ipf/EbcLowLevel.s
Adjust directory structures.
[mirror_edk2.git] / MdeModulePkg / Universal / EbcDxe / Ipf / EbcLowLevel.s
1 //++
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
7 //
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.
10 //
11 // Module Name:
12 //
13 // EbcLowLevel.s
14 //
15 // Abstract:
16 //
17 // Contains low level routines for the Virtual Machine implementation
18 // on an Itanium-based platform.
19 //
20 //
21 //--
22
23 .file "EbcLowLevel.s"
24
25 #define PROCEDURE_ENTRY(name) .##text; \
26 .##type name, @function; \
27 .##proc name; \
28 name::
29
30 #define PROCEDURE_EXIT(name) .##endp name
31
32 // Note: use of NESTED_SETUP requires number of locals (l) >= 3
33
34 #define NESTED_SETUP(i,l,o,r) \
35 alloc loc1=ar##.##pfs,i,l,o,r ;\
36 mov loc0=b0
37
38 #define NESTED_RETURN \
39 mov b0=loc0 ;\
40 mov ar##.##pfs=loc1 ;;\
41 br##.##ret##.##dpnt b0;;
42
43 .type CopyMem, @function;
44
45 //-----------------------------------------------------------------------------
46 //++
47 // EbcAsmLLCALLEX
48 //
49 // Implements the low level EBC CALLEX instruction. Sets up the
50 // stack pointer, does the spill of function arguments, and
51 // calls the native function. On return it restores the original
52 // stack pointer and returns to the caller.
53 //
54 // Arguments :
55 //
56 // On Entry :
57 // in0 = Address of native code to call
58 // in1 = New stack pointer
59 //
60 // Return Value:
61 //
62 // As per static calling conventions.
63 //
64 //--
65 //---------------------------------------------------------------------------
66 ;// void EbcAsmLLCALLEX (UINTN FunctionAddr, UINTN EbcStackPointer)
67 PROCEDURE_ENTRY(EbcAsmLLCALLEX)
68 NESTED_SETUP (2,6,8,0)
69
70 // NESTED_SETUP uses loc0 and loc1 for context save
71
72 //
73 // Save a copy of the EBC VM stack pointer
74 //
75 mov r8 = in1;;
76
77 //
78 // Copy stack arguments from EBC stack into registers.
79 // Assume worst case and copy 8.
80 //
81 ld8 out0 = [r8], 8;;
82 ld8 out1 = [r8], 8;;
83 ld8 out2 = [r8], 8;;
84 ld8 out3 = [r8], 8;;
85 ld8 out4 = [r8], 8;;
86 ld8 out5 = [r8], 8;;
87 ld8 out6 = [r8], 8;;
88 ld8 out7 = [r8], 8;;
89
90 //
91 // Save the original stack pointer
92 //
93 mov loc2 = r12;
94
95 //
96 // Save the gp
97 //
98 or loc3 = r1, r0
99
100 //
101 // Set the new aligned stack pointer. Reserve space for the required
102 // 16-bytes of scratch area as well.
103 //
104 add r12 = 48, in1
105
106 //
107 // Now call the function. Load up the function address from the descriptor
108 // pointed to by in0. Then get the gp from the descriptor at the following
109 // address in the descriptor.
110 //
111 ld8 r31 = [in0], 8;;
112 ld8 r30 = [in0];;
113 mov b1 = r31
114 mov r1 = r30
115 (p0) br.call.dptk.many b0 = b1;;
116
117 //
118 // Restore the original stack pointer and gp
119 //
120 mov r12 = loc2
121 or r1 = loc3, r0
122
123 //
124 // Now return
125 //
126 NESTED_RETURN
127
128 PROCEDURE_EXIT(EbcAsmLLCALLEX)
129
130 PROCEDURE_ENTRY(EbcLLCALLEXNative)
131 NESTED_SETUP (3,6,3,0)
132
133 mov loc2 = in2;;
134 mov loc3 = in1;;
135 sub loc2 = loc2, loc3
136 mov loc4 = r12;;
137 or loc5 = r1, r0
138
139 sub r12 = r12, loc2
140 mov out2 = loc2;;
141
142 and r12 = -0x10, r12
143 mov out1 = in1;;
144 mov out0 = r12;;
145 adds r12 = -0x8, r12
146 (p0) br.call.dptk.many b0 = CopyMem;;
147 adds r12 = 0x8, r12
148
149 mov out0 = in0;;
150 mov out1 = r12;;
151 (p0) br.call.dptk.many b0 = EbcAsmLLCALLEX;;
152 mov r12 = loc4;;
153 or r1 = loc5, r0
154
155 NESTED_RETURN
156 PROCEDURE_EXIT(EbcLLCALLEXNative)
157
158
159 //
160 // UINTN EbcLLGetEbcEntryPoint(VOID)
161 //
162 // Description:
163 // Simply return, so that the caller retrieves the return register
164 // contents (R8). That's where the thunk-to-ebc code stuffed the
165 // EBC entry point.
166 //
167 PROCEDURE_ENTRY(EbcLLGetEbcEntryPoint)
168 br.ret.sptk b0 ;;
169 PROCEDURE_EXIT(EbcLLGetEbcEntryPoint)
170
171 //
172 // INT64 EbcLLGetReturnValue(VOID)
173 //
174 // Description:
175 // This function is called to get the value returned by native code
176 // to EBC. It simply returns because the return value should still
177 // be in the register, so the caller just gets the unmodified value.
178 //
179 PROCEDURE_ENTRY(EbcLLGetReturnValue)
180 br.ret.sptk b0 ;;
181 PROCEDURE_EXIT(EbcLLGetReturnValue)
182
183 //
184 // UINTN EbcLLGetStackPointer(VOID)
185 //
186 PROCEDURE_ENTRY(EbcLLGetStackPointer)
187 mov r8 = r12 ;;
188 br.ret.sptk b0 ;;
189 br.sptk.few b6
190 PROCEDURE_EXIT(EbcLLGetStackPointer)
191
192
193
194
195
196
197