1/** @file
2  64-bit Math Worker Function.
3  The 32-bit versions of C compiler generate calls to library routines
4  to handle 64-bit math. These functions use non-standard calling conventions.
5
6  Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
7  This program and the accompanying materials are licensed and made available
8  under the terms and conditions of the BSD License which accompanies this
9  distribution.  The full text of the license may be found at
10  http://opensource.org/licenses/bsd-license.php.
11
12  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14
15**/
16
17#include <Library/BaseLib.h>
18
19
20/*
21 * Divides a 64-bit signed value by another 64-bit signed value and returns
22 * the 64-bit signed result and the 64-bit signed remainder.
23 */
24__declspec(naked) void __cdecl _aulldvrm(void)
25{
26  //
27  // Wrapper Implementation over EDKII DivU64x64Remainder() routine
28  //    UINT64
29  //    EFIAPI
30  //    DivU64x64Remainder (
31  //      IN      UINT64     Dividend,
32  //      IN      UINT64     Divisor,
33  //      OUT     UINT64     *Remainder
34  //      )
35  //
36  _asm {
37    ; Original local stack when calling _aulldvrm
38    ;               -----------------
39    ;               |               |
40    ;               |---------------|
41    ;               |               |
42    ;               |--  Divisor  --|
43    ;               |               |
44    ;               |---------------|
45    ;               |               |
46    ;               |--  Dividend --|
47    ;               |               |
48    ;               |---------------|
49    ;               |  ReturnAddr** |
50    ;       ESP---->|---------------|
51    ;
52    ;
53    ; On Exit:
54    ;       EDX:EAX contains the quotient (dividend/divisor)
55    ;       EBX:ECX contains the remainder (divided % divisor)
56    ;       NOTE: this routine removes the parameters from the stack.
57    ;
58
59    ;
60    ; Set up the local stack for Remainder pointer
61    ;
62    sub  esp, 8
63    push esp
64
65    ;
66    ; Set up the local stack for Divisor parameter
67    ;
68    mov  eax, [esp + 28]
69    push eax
70    mov  eax, [esp + 28]
71    push eax
72
73    ;
74    ; Set up the local stack for Dividend parameter
75    ;
76    mov  eax, [esp + 28]
77    push eax
78    mov  eax, [esp + 28]
79    push eax
80
81    ;
82    ; Call native DivU64x64Remainder of BaseLib
83    ;
84    call DivU64x64Remainder
85
86    ;
87    ; EDX:EAX contains the quotient (dividend/divisor)
88    ; Put the Remainder in EBX:ECX
89    ;
90    mov  ecx, [esp + 20]
91    mov  ebx, [esp + 24]
92
93    ;
94    ; Adjust stack
95    ;
96    add  esp, 28
97
98    ret  16
99  }
100}
101