source: mainline/boot/arch/ia64/loader/gefi/lib/ia32/math.c@ 7208b6c

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 7208b6c was 7208b6c, checked in by Jakub Vana <jakub.vana@…>, 17 years ago

Basic IA64 boot and kernel suport for real machines

  • Property mode set to 100644
File size: 3.3 KB
Line 
1/*++
2
3Copyright (c) 1998 Intel Corporation
4
5Module Name:
6
7 math.c
8
9Abstract:
10
11
12
13
14Revision History
15
16--*/
17
18#include "lib.h"
19
20
21//
22// Declare runtime functions
23//
24
25#ifdef RUNTIME_CODE
26#pragma RUNTIME_CODE(LShiftU64)
27#pragma RUNTIME_CODE(RShiftU64)
28#pragma RUNTIME_CODE(MultU64x32)
29#pragma RUNTIME_CODE(DivU64x32)
30#endif
31
32//
33//
34//
35
36UINT64
37LShiftU64 (
38 IN UINT64 Operand,
39 IN UINTN Count
40 )
41// Left shift 64bit by 32bit and get a 64bit result
42{
43#ifdef __GNUC__
44 return Operand << Count;
45#else
46 UINT64 Result;
47 _asm {
48 mov eax, dword ptr Operand[0]
49 mov edx, dword ptr Operand[4]
50 mov ecx, Count
51 and ecx, 63
52
53 shld edx, eax, cl
54 shl eax, cl
55
56 cmp ecx, 32
57 jc short ls10
58
59 mov edx, eax
60 xor eax, eax
61
62ls10:
63 mov dword ptr Result[0], eax
64 mov dword ptr Result[4], edx
65 }
66
67 return Result;
68#endif
69}
70
71UINT64
72RShiftU64 (
73 IN UINT64 Operand,
74 IN UINTN Count
75 )
76// Right shift 64bit by 32bit and get a 64bit result
77{
78#ifdef __GNUC__
79 return Operand >> Count;
80#else
81 UINT64 Result;
82 _asm {
83 mov eax, dword ptr Operand[0]
84 mov edx, dword ptr Operand[4]
85 mov ecx, Count
86 and ecx, 63
87
88 shrd eax, edx, cl
89 shr edx, cl
90
91 cmp ecx, 32
92 jc short rs10
93
94 mov eax, edx
95 xor edx, edx
96
97rs10:
98 mov dword ptr Result[0], eax
99 mov dword ptr Result[4], edx
100 }
101
102 return Result;
103#endif
104}
105
106
107UINT64
108MultU64x32 (
109 IN UINT64 Multiplicand,
110 IN UINTN Multiplier
111 )
112// Multiple 64bit by 32bit and get a 64bit result
113{
114#ifdef __GNUC__
115 return Multiplicand * Multiplier;
116#else
117 UINT64 Result;
118 _asm {
119 mov eax, dword ptr Multiplicand[0]
120 mul Multiplier
121 mov dword ptr Result[0], eax
122 mov dword ptr Result[4], edx
123 mov eax, dword ptr Multiplicand[4]
124 mul Multiplier
125 add dword ptr Result[4], eax
126 }
127
128 return Result;
129#endif
130}
131
132UINT64
133DivU64x32 (
134 IN UINT64 Dividend,
135 IN UINTN Divisor,
136 OUT UINTN *Remainder OPTIONAL
137 )
138// divide 64bit by 32bit and get a 64bit result
139// N.B. only works for 31bit divisors!!
140{
141#ifdef __GNUC__
142 if (Remainder)
143 *Remainder = Dividend % Divisor;
144 return Dividend / Divisor;
145#else
146 UINT32 Rem;
147 UINT32 bit;
148
149 ASSERT (Divisor != 0);
150 ASSERT ((Divisor >> 31) == 0);
151
152 //
153 // For each bit in the dividend
154 //
155
156 Rem = 0;
157 for (bit=0; bit < 64; bit++) {
158 _asm {
159 shl dword ptr Dividend[0], 1 ; shift rem:dividend left one
160 rcl dword ptr Dividend[4], 1
161 rcl dword ptr Rem, 1
162
163 mov eax, Rem
164 cmp eax, Divisor ; Is Rem >= Divisor?
165 cmc ; No - do nothing
166 sbb eax, eax ; Else,
167 sub dword ptr Dividend[0], eax ; set low bit in dividen
168 and eax, Divisor ; and
169 sub Rem, eax ; subtract divisor
170 }
171 }
172
173 if (Remainder) {
174 *Remainder = Rem;
175 }
176
177 return Dividend;
178#endif
179}
Note: See TracBrowser for help on using the repository browser.