summaryrefslogtreecommitdiff
path: root/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/DivU64x32.S
blob: edf0dd7042b2bead30c0a6a746667e5da327b08d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#---------------------------------------------------------------------------
#/*++
#
#Copyright (c) 2006, Intel Corporation                                                         
#All rights reserved. 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        
#http://opensource.org/licenses/bsd-license.php                                            
#                                                                                          
#THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
#WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
#
#Module Name:
#
#  DivU64x32.c
#
#Abstract:
#
#  64-bit division function for IA-32
#
#--*/

#---------------------------------------------------------------------------
#include "EfiBind.h" //For ASM_PFX
#---------------------------------------------------------------------------

#---------------------------------------------------------------------------
    .386: 
    .code: 

#---------------------------------------------------------------------------

.globl ASM_PFX(DivU64x32)

#UINT64
#DivU64x32 (
#  IN UINT64   Dividend,
#  IN UINTN    Divisor,
#  OUT UINTN   *Remainder OPTIONAL
#  )
#/*++

#Routine Description:

#  This routine allows a 64 bit value to be divided with a 32 bit value returns 
#  64bit result and the Remainder.
#
#Arguments:

#  Dividend  - dividend
#  Divisor   - divisor
#  Remainder - buffer for remainder
#  
#Returns:

#  Dividend  / Divisor
#  Remainder = Dividend mod Divisor
#  
#N.B. only works for 31bit divisors!!
#
#--*/
#---------------------------------------------------------------------------

ASM_PFX(DivU64x32):
    pushl %ebp
    movl %esp, %ebp
    xorl %edx, %edx                 # Clear EDX

    movl 0xC(%ebp), %eax            # Put high 32 bits of 64-bit dividend in EAX
    movl 0x10(%ebp), %ecx           # Put 32 bits divisor in ECX
    divl %ecx                       # Dividend   Divisor  Quoitent...Remainder
                                    #  0:EAX  /  ECX   =  EAX      EDX   

    pushl %eax                      # Push quoitent in stack

    movl 8(%ebp), %eax              # Put low 32 bits of 64-bit dividend in EAX              
    divl %ecx                       # Leave the REMAINDER in EDX as High 32-bit of new dividend
                                    # Dividend   Divisor  Quoitent...Remainder              
                                    #  EDX:EAX  /  ECX   =  EAX      EDX               

    movl 0x14(%ebp), %ecx            # Put &REMAINDER to ecx

    jecxz Label1                    # If ecx == 0, no remainder exist, return with quoitent in EDX directly 
    movl %edx, (%ecx)               # Put EDX through REMAINDER pointer in ECX 

Label1: 
    popl %edx                       # Pop High 32-bit QUOITENT to EDX
    popl %ebp

    ret