1 ;****************************************************************************
3 ;* SciTech OS Portability Manager Library
5 ;* ========================================================================
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
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.
17 ;* The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc.
19 ;* The Initial Developer of the Original Code is SciTech Software, Inc.
20 ;* All Rights Reserved.
22 ;* ========================================================================
24 ;* Language: NASM or TASM Assembler
25 ;* Environment: Intel 32 bit Protected Mode.
27 ;* Description: Code for 64-bit arhithmetic
29 ;****************************************************************************
37 begcodeseg _int64 ; Start of code segment
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
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 ;----------------------------------------------------------------------------
59 mov ecx,[esp+result_4]
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 ;----------------------------------------------------------------------------
77 mov ecx,[esp+result_4]
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 ;----------------------------------------------------------------------------
96 mov eax,[esp+a_low] ; EDX:EAX = b.low * a.low
98 mov ecx,[esp+result_4]
105 mul ecx ; EDX:EAX = a.high * b.low
107 mov eax,[esp+a_low+4]
108 mul [DWORD esp+b_high+4] ; EDX:EAX = b.high * a.low
110 mov eax,[esp+a_low+4]
111 mul ecx ; EDX:EAX = a.low * b.low
114 mov ecx,[esp+result_4]
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 ;----------------------------------------------------------------------------
132 mov eax,[esp+a_high+0Ch]
136 ; Dividend is negative, so negate it and save result for later
139 mov edx,[esp+a_low+0Ch]
143 mov [esp+a_high+0Ch],eax
144 mov [esp+a_low+0Ch],edx
147 mov eax,[esp+b_high+0Ch]
151 ; Divisor is negative, so negate it and save result for later
154 mov edx,[esp+b_low+0Ch]
158 mov [esp+b_high+0Ch],eax
159 mov [esp+b_low+0Ch],edx
165 ; b.high is zero, so handle this faster
167 mov ecx,[esp+b_low+0Ch]
168 mov eax,[esp+a_high+0Ch]
172 mov eax,[esp+a_low+0Ch]
179 mov ecx,[esp+b_low+0Ch]
180 mov edx,[esp+a_high+0Ch]
181 mov eax,[esp+a_low+0Ch]
183 ; Shift values right until b.high becomes zero
193 ; Now complete the divide process
197 mul [DWORD esp+b_high+0Ch]
199 mov eax,[esp+b_low+0Ch]
203 cmp edx,[esp+a_high+0Ch]
206 cmp eax,[esp+a_low+0Ch]
216 ; The result needs to be negated as either a or b was negative
225 mov ecx,[esp+result_4]
232 ;----------------------------------------------------------------------------
233 ; __i64 _PM_shr64(u32 a_low,s32 a_high,s32 shift,__u64 *result);
234 ;----------------------------------------------------------------------------
235 ; Shift a 64-bit number right
236 ;----------------------------------------------------------------------------
243 mov ecx,[esp+result_3]
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 ;----------------------------------------------------------------------------
262 mov ecx,[esp+result_3]
269 ;----------------------------------------------------------------------------
270 ; __i64 _PM_shl64(u32 a_low,s32 a_high,s32 shift,__u64 *result);
271 ;----------------------------------------------------------------------------
272 ; Shift a 64-bit number left
273 ;----------------------------------------------------------------------------
280 mov ecx,[esp+result_3]
287 ;----------------------------------------------------------------------------
288 ; __i64 _PM_neg64(u32 a_low,s32 a_high,__u64 *result);
289 ;----------------------------------------------------------------------------
290 ; Shift a 64-bit number left
291 ;----------------------------------------------------------------------------
299 mov ecx,[esp+result_2]