Allow EbcLowLevel.S to be linked correctly with 'ELFGCC' toolchain.
[edk2.git] / MdeModulePkg / Universal / EbcDxe / X64 / EbcLowLevel.S
blob3b86b53ab099dba8e9705f38ed4bcb868ce76dab
1 #/** @file\r
2 #  \r
3 #    This code provides low level routines that support the Virtual Machine\r
4 #   for option ROMs.\r
5 #  \r
6 #  Copyright (c) 2007 - 2008, Intel Corporation. <BR>\r
7 #  All rights reserved. This program and the accompanying materials\r
8 #  are licensed and made available under the terms and conditions of the BSD License\r
9 #  which accompanies this distribution.  The full text of the license may be found at\r
10 #  http://opensource.org/licenses/bsd-license.php\r
11 #  \r
12 #  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13 #  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
14 #  \r
15 #**/\r
17 #---------------------------------------------------------------------------\r
18 # Equate files needed.\r
19 #---------------------------------------------------------------------------\r
21 #---------------------------------------------------------------------------\r
22 ##GenericPostSegment      SEGMENT USE16\r
23 #---------------------------------------------------------------------------\r
25 #****************************************************************************\r
26 # EbcLLCALLEX\r
27 #\r
28 # This function is called to execute an EBC CALLEX instruction.\r
29 # This instruction requires that we thunk out to external native\r
30 # code. For x64, we switch stacks, copy the arguments to the stack\r
31 # and jump to the specified function.\r
32 # On return, we restore the stack pointer to its original location.\r
33 #\r
34 # Destroys no working registers.\r
35 #****************************************************************************\r
36 .global _CopyMem;\r
38 # VOID EbcLLCALLEXNative(UINTN FuncAddr, UINTN NewStackPointer, VOID *FramePtr)\r
39 .global ASM_PFX(EbcLLCALLEXNative);\r
40 ASM_PFX(EbcLLCALLEXNative):\r
41       push   %rbp\r
42       push   %rbx\r
43       mov    %rsp, %rbp\r
44       # Function prolog\r
46       # Copy FuncAddr to a preserved register.\r
47       mov    %rcx, %rbx\r
49       # Set stack pointer to new value\r
50       sub    %r8,  %rdx\r
51       sub    %rsp, %r8\r
52       mov    %rsp, %rcx\r
53       sub    %rsp, 0x20\r
54       call   ASM_PFX(CopyMem)\r
55       add    %rsp, 0x20\r
57       # Considering the worst case, load 4 potiential arguments\r
58       # into registers.\r
59       mov    (%rsp), %rcx\r
60       mov    8(%rsp), %rdx\r
61       mov    10(%rsp), %r8\r
62       mov    18(%rsp), %r9\r
64       # Now call the external routine\r
65       call  *%rbx\r
67       # Function epilog\r
68       mov      %rbp, %rsp\r
69       pop      %rbx\r
70       pop      %rbp\r
71       ret\r
74 # UINTN EbcLLGetEbcEntryPoint(VOID);\r
75 # Routine Description:\r
76 #   The VM thunk code stuffs an EBC entry point into a processor\r
77 #   register. Since we can't use inline assembly to get it from\r
78 #   the interpreter C code, stuff it into the return value\r
79 #   register and return.\r
80 #\r
81 # Arguments:\r
82 #     None.\r
83 #\r
84 # Returns:\r
85 #     The contents of the register in which the entry point is passed.\r
86 #\r
87 .global ASM_PFX(EbcLLGetEbcEntryPoint);\r
88 ASM_PFX(EbcLLGetEbcEntryPoint):\r
89     ret\r
91 #/*++\r
92 #\r
93 #Routine Description:\r
94 #\r
95 #  Return the caller's value of the stack pointer.\r
96 #\r
97 #Arguments:\r
98 #\r
99 #  None.\r
101 #Returns:\r
103 #  The current value of the stack pointer for the caller. We\r
104 #  adjust it by 4 here because when they called us, the return address\r
105 #  is put on the stack, thereby lowering it by 4 bytes.\r
107 #--*/\r
109 # UINTN EbcLLGetStackPointer()\r
110 .global ASM_PFX(EbcLLGetStackPointer);\r
111 ASM_PFX(EbcLLGetStackPointer):\r
112     mov    %rsp, %rax\r
113     # Stack adjusted by this much when we were called,\r
114     # For this function, it's 4.\r
115     add   $4, %rax\r
116     ret\r
118 .global ASM_PFX(EbcLLGetReturnValue);\r
119 ASM_PFX(EbcLLGetReturnValue):\r
120 # UINT64 EbcLLGetReturnValue(VOID);\r
121 # Routine Description:\r
122 #   When EBC calls native, on return the VM has to stuff the return\r
123 #   value into a VM register. It's assumed here that the value is still\r
124 #    in the register, so simply return and the caller should get the\r
125 #   return result properly.\r
127 # Arguments:\r
128 #     None.\r
130 # Returns:\r
131 #     The unmodified value returned by the native code.\r
133     ret\r