Coding style cleanup
[platform/kernel/u-boot.git] / board / MAI / bios_emulator / scitech / src / pm / common / _int64.asm
1 ;****************************************************************************
2 ;*
3 ;*                  SciTech OS Portability Manager Library
4 ;*
5 ;*  ========================================================================
6 ;*
7 ;*    The contents of this file are subject to the SciTech MGL Public
8 ;*    License Version 1.0 (the "License"); you may not use this file
9 ;*    except in compliance with the License. You may obtain a copy of
10 ;*    the License at http://www.scitechsoft.com/mgl-license.txt
11 ;*
12 ;*    Software distributed under the License is distributed on an
13 ;*    "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
14 ;*    implied. See the License for the specific language governing
15 ;*    rights and limitations under the License.
16 ;*
17 ;*    The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc.
18 ;*
19 ;*    The Initial Developer of the Original Code is SciTech Software, Inc.
20 ;*    All Rights Reserved.
21 ;*
22 ;*  ========================================================================
23 ;*
24 ;* Language:    NASM or TASM Assembler
25 ;* Environment: Intel 32 bit Protected Mode.
26 ;*
27 ;* Description: Code for 64-bit arhithmetic
28 ;*
29 ;****************************************************************************
30
31         IDEAL
32
33 include "scitech.mac"
34
35 header      _int64
36
37 begcodeseg  _int64                  ; Start of code segment
38
39 a_low       EQU 04h                 ; Access a_low directly on stack
40 a_high      EQU 08h                 ; Access a_high directly on stack
41 b_low       EQU 0Ch                 ; Access b_low directly on stack
42 shift       EQU 0Ch                 ; Access shift directly on stack
43 result_2    EQU 0Ch                 ; Access result directly on stack
44 b_high      EQU 10h                 ; Access b_high directly on stack
45 result_3    EQU 10h                 ; Access result directly on stack
46 result_4    EQU 14h                 ; Access result directly on stack
47
48 ;----------------------------------------------------------------------------
49 ; void _PM_add64(u32 a_low,u32 a_high,u32 b_low,u32 b_high,__u64 *result);
50 ;----------------------------------------------------------------------------
51 ; Adds two 64-bit numbers.
52 ;----------------------------------------------------------------------------
53 cprocstart  _PM_add64
54
55         mov     eax,[esp+a_low]
56         add     eax,[esp+b_low]
57         mov     edx,[esp+a_high]
58         adc     edx,[esp+b_high]
59         mov     ecx,[esp+result_4]
60         mov     [ecx],eax
61         mov     [ecx+4],edx
62         ret
63
64 cprocend
65
66 ;----------------------------------------------------------------------------
67 ; void _PM_sub64(u32 a_low,u32 a_high,u32 b_low,u32 b_high,__u64 *result);
68 ;----------------------------------------------------------------------------
69 ; Subtracts two 64-bit numbers.
70 ;----------------------------------------------------------------------------
71 cprocstart  _PM_sub64
72
73         mov     eax,[esp+a_low]
74         sub     eax,[esp+b_low]
75         mov     edx,[esp+a_high]
76         sbb     edx,[esp+b_high]
77         mov     ecx,[esp+result_4]
78         mov     [ecx],eax
79         mov     [ecx+4],edx
80         ret
81
82 cprocend
83
84 ;----------------------------------------------------------------------------
85 ; void _PM_mul64(u32 a_high,u32 a_low,u32 b_high,u32 b_low,__u64 *result);
86 ;----------------------------------------------------------------------------
87 ; Multiples two 64-bit numbers.
88 ;----------------------------------------------------------------------------
89 cprocstart  _PM_mul64
90
91         mov     eax,[esp+a_high]
92         mov     ecx,[esp+b_high]
93         or      ecx,eax
94         mov     ecx,[esp+b_low]
95         jnz     @@FullMultiply
96         mov     eax,[esp+a_low]         ; EDX:EAX = b.low * a.low
97         mul     ecx
98         mov     ecx,[esp+result_4]
99         mov     [ecx],eax
100         mov     [ecx+4],edx
101         ret
102
103 @@FullMultiply:
104         push    ebx
105         mul     ecx                     ; EDX:EAX = a.high * b.low
106         mov     ebx,eax
107         mov     eax,[esp+a_low+4]
108         mul     [DWORD esp+b_high+4]    ; EDX:EAX = b.high * a.low
109         add     ebx,eax
110         mov     eax,[esp+a_low+4]
111         mul     ecx                     ; EDX:EAX = a.low * b.low
112         add     edx,ebx
113         pop     ebx
114         mov     ecx,[esp+result_4]
115         mov     [ecx],eax
116         mov     [ecx+4],edx
117         ret
118
119 cprocend
120
121 ;----------------------------------------------------------------------------
122 ; void _PM_div64(u32 a_low,u32 a_high,u32 b_low,u32 b_high,__u64 *result);
123 ;----------------------------------------------------------------------------
124 ; Divides two 64-bit numbers.
125 ;----------------------------------------------------------------------------
126 cprocstart  _PM_div64
127
128         push    edi
129         push    esi
130         push    ebx
131         xor     edi,edi
132         mov     eax,[esp+a_high+0Ch]
133         or      eax,eax
134         jns     @@ANotNeg
135
136 ; Dividend is negative, so negate it and save result for later
137
138         inc     edi
139         mov     edx,[esp+a_low+0Ch]
140         neg     eax
141         neg     edx
142         sbb     eax,0
143         mov     [esp+a_high+0Ch],eax
144         mov     [esp+a_low+0Ch],edx
145
146 @@ANotNeg:
147         mov     eax,[esp+b_high+0Ch]
148         or      eax,eax
149         jns     @@BNotNeg
150
151 ; Divisor is negative, so negate it and save result for later
152
153         inc     edi
154         mov     edx,[esp+b_low+0Ch]
155         neg     eax
156         neg     edx
157         sbb     eax,0
158         mov     [esp+b_high+0Ch],eax
159         mov     [esp+b_low+0Ch],edx
160
161 @@BNotNeg:
162         or      eax,eax
163         jnz     @@BHighNotZero
164
165 ; b.high is zero, so handle this faster
166
167         mov     ecx,[esp+b_low+0Ch]
168         mov     eax,[esp+a_high+0Ch]
169         xor     edx,edx
170         div     ecx
171         mov     ebx,eax
172         mov     eax,[esp+a_low+0Ch]
173         div     ecx
174         mov     edx,ebx
175         jmp     @@BHighZero
176
177 @@BHighNotZero:
178         mov     ebx,eax
179         mov     ecx,[esp+b_low+0Ch]
180         mov     edx,[esp+a_high+0Ch]
181         mov     eax,[esp+a_low+0Ch]
182
183 ; Shift values right until b.high becomes zero
184
185 @@ShiftLoop:
186         shr     ebx,1
187         rcr     ecx,1
188         shr     edx,1
189         rcr     eax,1
190         or      ebx,ebx
191         jnz     @@ShiftLoop
192
193 ; Now complete the divide process
194
195         div     ecx
196         mov     esi,eax
197         mul     [DWORD esp+b_high+0Ch]
198         mov     ecx,eax
199         mov     eax,[esp+b_low+0Ch]
200         mul     esi
201         add     edx,ecx
202         jb      @@8
203         cmp     edx,[esp+a_high+0Ch]
204         ja      @@8
205         jb      @@9
206         cmp     eax,[esp+a_low+0Ch]
207         jbe     @@9
208 @@8:    dec     esi
209 @@9:    xor     edx,edx
210         mov     eax,esi
211
212 @@BHighZero:
213         dec     edi
214         jnz     @@Done
215
216 ; The result needs to be negated as either a or b was negative
217
218         neg     edx
219         neg     eax
220         sbb     edx,0
221
222 @@Done: pop     ebx
223         pop     esi
224         pop     edi
225         mov     ecx,[esp+result_4]
226         mov     [ecx],eax
227         mov     [ecx+4],edx
228         ret
229
230 cprocend
231
232 ;----------------------------------------------------------------------------
233 ; __i64 _PM_shr64(u32 a_low,s32 a_high,s32 shift,__u64 *result);
234 ;----------------------------------------------------------------------------
235 ; Shift a 64-bit number right
236 ;----------------------------------------------------------------------------
237 cprocstart  _PM_shr64
238
239         mov     eax,[esp+a_low]
240         mov     edx,[esp+a_high]
241         mov     cl,[esp+shift]
242         shrd    edx,eax,cl
243         mov     ecx,[esp+result_3]
244         mov     [ecx],eax
245         mov     [ecx+4],edx
246         ret
247
248 cprocend
249
250 ;----------------------------------------------------------------------------
251 ; __i64 _PM_sar64(u32 a_low,s32 a_high,s32 shift,__u64 *result);
252 ;----------------------------------------------------------------------------
253 ; Shift a 64-bit number right (signed)
254 ;----------------------------------------------------------------------------
255 cprocstart  _PM_sar64
256
257         mov     eax,[esp+a_low]
258         mov     edx,[esp+a_high]
259         mov     cl,[esp+shift]
260         sar     edx,cl
261         rcr     eax,cl
262         mov     ecx,[esp+result_3]
263         mov     [ecx],eax
264         mov     [ecx+4],edx
265         ret
266
267 cprocend
268
269 ;----------------------------------------------------------------------------
270 ; __i64 _PM_shl64(u32 a_low,s32 a_high,s32 shift,__u64 *result);
271 ;----------------------------------------------------------------------------
272 ; Shift a 64-bit number left
273 ;----------------------------------------------------------------------------
274 cprocstart  _PM_shl64
275
276         mov     eax,[esp+a_low]
277         mov     edx,[esp+a_high]
278         mov     cl,[esp+shift]
279         shld    edx,eax,cl
280         mov     ecx,[esp+result_3]
281         mov     [ecx],eax
282         mov     [ecx+4],edx
283         ret
284
285 cprocend
286
287 ;----------------------------------------------------------------------------
288 ; __i64 _PM_neg64(u32 a_low,s32 a_high,__u64 *result);
289 ;----------------------------------------------------------------------------
290 ; Shift a 64-bit number left
291 ;----------------------------------------------------------------------------
292 cprocstart  _PM_neg64
293
294         mov     eax,[esp+a_low]
295         mov     edx,[esp+a_high]
296         neg     eax
297         neg     edx
298         sbb     eax,0
299         mov     ecx,[esp+result_2]
300         mov     [ecx],eax
301         mov     [ecx+4],edx
302         ret
303
304 cprocend
305
306
307 endcodeseg  _int64
308
309         END