5 * Core floating point subtraction routine.
8 * void reg_u_sub(FPU_REG *arg1, FPU_REG *arg2, FPU_REG *answ,
12 * Copyright (C) 1992,1993,1994
13 * W. Metzenthen, 22 Parker St, Ormond, Vic 3163,
14 * Australia. E-mail billm@vaxc.cc.monash.edu.au
15 * All rights reserved.
17 * This copyright notice covers the redistribution and use of the
18 * FPU emulator developed by W. Metzenthen. It covers only its use
19 * in the 386BSD, FreeBSD and NetBSD operating systems. Any other
20 * use is not permitted under this copyright.
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions
25 * 1. Redistributions of source code must retain the above copyright
26 * notice, this list of conditions and the following disclaimer.
27 * 2. Redistributions in binary form must include information specifying
28 * that source code for the emulator is freely available and include
30 * a) an offer to provide the source code for a nominal distribution
32 * b) list at least two alternative methods whereby the source
33 * can be obtained, e.g. a publically accessible bulletin board
34 * and an anonymous ftp site from which the software can be
36 * 3. All advertising materials specifically mentioning features or use of
37 * this emulator must acknowledge that it was developed by W. Metzenthen.
38 * 4. The name of W. Metzenthen may not be used to endorse or promote
39 * products derived from this software without specific prior written
42 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
43 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
44 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
45 * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
46 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
47 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
48 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
49 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
50 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
51 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 * The purpose of this copyright, based upon the Berkeley copyright, is to
55 * ensure that the covered software remains freely available to everyone.
57 * The software (with necessary differences) is also available, but under
58 * the terms of the GNU copyleft, for the Linux operating system and for
59 * the djgpp ms-dos extender.
61 * W. Metzenthen June 1994.
64 * $FreeBSD: src/sys/gnu/i386/fpemul/reg_u_sub.s,v 1.9 1999/08/28 00:42:58 peter Exp $
65 * $DragonFly: src/sys/i386/gnu/fpemul/Attic/reg_u_sub.s,v 1.4 2003/08/07 21:17:21 dillon Exp $
70 | Kernel subtraction routine reg_u_sub(reg *arg1, reg *arg2, reg *answ).
71 | Takes two valid reg f.p. numbers (TW_Valid), which are
72 | treated as unsigned numbers,
73 | and returns their difference as a TW_Valid or TW_Zero f.p.
75 | The first number (arg1) must be the larger.
76 | The returned number is normalized.
77 | Basic checks are performed if PARANOID is defined.
90 movl PARAM1,%esi /* source 1 */
91 movl PARAM2,%edi /* source 2 */
94 cmpl EXP_UNDER,EXP(%esi)
102 cmpl EXP_UNDER,EXP(%edi)
105 call denormal_operand
110 #endif DENORM_OPERAND
114 subl EXP(%edi),%ecx /* exp1 - exp2 */
117 /* source 2 is always smaller than source 1 */
121 testl $0x80000000,SIGH(%edi) /* The args are assumed to be be normalized */
124 testl $0x80000000,SIGH(%esi)
128 /*--------------------------------------+
129 | Form a register holding the |
131 +--------------------------------------*/
132 movl SIGH(%edi),%eax /* register ms word */
133 movl SIGL(%edi),%ebx /* register ls word */
135 movl PARAM3,%edi /* destination */
137 movl %edx,EXP(%edi) /* Copy exponent to destination */
139 movb %dl,SIGN(%edi) /* Copy the sign from the first arg */
141 xorl %edx,%edx /* register extension */
143 /*--------------------------------------+
144 | Shift the temporary register |
145 | right the required number of |
147 +--------------------------------------*/
149 cmpl $32,%ecx /* shrd only works for 0..31 bits */
152 /* less than 32 bits */
168 jz L_more_31_no_low /* none of the lowest bits is set */
170 orl $1,%edx /* record the fact in the extension */
187 /* Shift right by 64 bits */
198 /* Shift right by 65 bits */
199 /* Carry is clear if we get here */
215 movl $1,%edx /* The shifted nr always at least one '1' */
223 /*------------------------------+
224 | Do the subtraction |
225 +------------------------------*/
237 /* We can never get a borrow */
241 /*--------------------------------------+
242 | Normalize the result |
243 +--------------------------------------*/
244 testl $0x80000000,%eax
245 jnz L_round /* no shifting needed */
248 jnz L_shift_1 /* shift left 1 - 31 bits */
251 jnz L_shift_32 /* shift left 32 - 63 bits */
253 /* A rare case, the only one which is non-zero if we got here
254 // is: 1000000 .... 0000
255 // -0111111 .... 1111 1
256 // --------------------
257 // 0000000 .... 0000 1 */
259 cmpl $0x80000000,%edx
262 /* Shift left 64 bits */
273 /* The result is zero */
274 movb TW_Zero,TAG(%edi)
275 movl $0,EXP(%edi) /* exponent */
278 jmp L_exit /* Does not underflow */
284 subl $32,EXP(%edi) /* Can get underflow here */
286 /* We need to shift left by 1 - 31 bits */
288 bsrl %eax,%ecx /* get the required shift in %ecx */
294 subl %ecx,EXP(%edi) /* Can get underflow here */
297 jmp FPU_round /* Round the result */
302 pushl EX_INTERNAL|0x206
308 pushl EX_INTERNAL|0x209
314 pushl EX_INTERNAL|0x210
320 pushl EX_INTERNAL|0x211
326 pushl EX_INTERNAL|0x212
334 /*------------------------------+
336 +------------------------------*/
340 movb TW_Valid,TAG(%edi) /* Set the tags to TW_Valid */
342 cmpl EXP_UNDER,EXP(%edi)