Subversion Repositories HelenOS

Rev

Rev 2726 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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