VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/asm/ASMMultU64ByU32DivByU32.asm@ 5999

Last change on this file since 5999 was 5999, checked in by vboxsync, 17 years ago

The Giant CDDL Dual-License Header Change.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 3.7 KB
Line 
1; $Id: ASMMultU64ByU32DivByU32.asm 5999 2007-12-07 15:05:06Z vboxsync $
2;; @file
3; innotek Portable Runtime - Assembly Functions, ASMMultU64ByU32DivByU32.
4;
5
6;
7; Copyright (C) 2006-2007 innotek GmbH
8;
9; This file is part of VirtualBox Open Source Edition (OSE), as
10; available from http://www.virtualbox.org. This file is free software;
11; you can redistribute it and/or modify it under the terms of the GNU
12; General Public License (GPL) as published by the Free Software
13; Foundation, in version 2 as it comes in the "COPYING" file of the
14; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16;
17; The contents of this file may alternatively be used under the terms
18; of the Common Development and Distribution License Version 1.0
19; (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20; VirtualBox OSE distribution, in which case the provisions of the
21; CDDL are applicable instead of those of the GPL.
22;
23; You may elect to license modified versions of this file under the
24; terms and conditions of either the GPL or the CDDL or both.
25;
26
27%include "iprt/asmdefs.mac"
28
29
30;;
31; Multiple a 64-bit by a 32-bit integer and divide the result by a 32-bit integer
32; using a 96 bit intermediate result.
33;
34; @returns (u64A * u32B) / u32C.
35; @param u64A/rcx/rdi The 64-bit value.
36; @param u32B/edx/esi The 32-bit value to multiple by A.
37; @param u32C/r8d/edx The 32-bit value to divide A*B by.
38;
39; @cproto DECLASM(uint64_t) ASMMultU64ByU32DivByU32(uint64_t u64A, uint32_t u32B, uint32_t u32C);
40;
41BEGINPROC_EXPORTED ASMMultU64ByU32DivByU32
42%ifdef RT_ARCH_AMD64
43
44 %ifdef ASM_CALL64_MSC
45 mov rax, rcx ; rax = u64A
46 mov r9d, edx ; should check the specs wrt to the high bits one day...
47 mov r8d, r8d ; be paranoid for the time being.
48 %else
49 mov rax, rdi ; rax = u64A
50 mov r9d, esi ; r9d = u32B
51 mov r8d, edx ; r8d = u32C
52 %endif
53 mul r9
54 div r8
55
56%else ; X86
57 ;
58 ; This implementation is convered from the GCC inline
59 ; version of the code. Nothing additional has been done
60 ; performance wise.
61 ;
62 push esi
63 push edi
64
65%define u64A_Lo [esp + 04h + 08h]
66%define u64A_Hi [esp + 08h + 08h]
67%define u32B [esp + 0ch + 08h]
68%define u32C [esp + 10h + 08h]
69
70 ; Load parameters into registers.
71 mov eax, u64A_Lo
72 mov esi, u64A_Hi
73 mov ecx, u32B
74 mov edi, u32C
75
76 ; The body, just like the in
77 mul ecx ; eax = u64Lo.lo = (u64A.lo * u32B).lo
78 ; edx = u64Lo.hi = (u64A.lo * u32B).hi
79 xchg eax, esi ; esi = u64Lo.lo
80 ; eax = u64A.hi
81 xchg edx, edi ; edi = u64Low.hi
82 ; edx = u32C
83 xchg edx, ecx ; ecx = u32C
84 ; edx = u32B
85 mul edx ; eax = u64Hi.lo = (u64A.hi * u32B).lo
86 ; edx = u64Hi.hi = (u64A.hi * u32B).hi
87 add eax, edi ; u64Hi.lo += u64Lo.hi
88 adc edx, 0 ; u64Hi.hi += carry
89 div ecx ; eax = u64Hi / u32C
90 ; edx = u64Hi % u32C
91 mov edi, eax ; edi = u64Result.hi = u64Hi / u32C
92 mov eax, esi ; eax = u64Lo.lo
93 div ecx ; u64Result.lo
94 mov edx, edi ; u64Result.hi
95
96 ; epilogue
97 pop edi
98 pop esi
99%endif
100 ret
101ENDPROC ASMMultU64ByU32DivByU32
102
103
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette