Get LINT to build.
[dragonfly.git] / sys / i386 / gnu / fpemul / reg_u_add.s
1         .file   "reg_u_add.S"
2 /*
3  *  reg_u_add.S
4  *
5  * Add two valid (TW_Valid) FPU_REG numbers, of the same sign, and put the
6  *   result in a destination FPU_REG.
7  *
8  * Call from C as:
9  *   void reg_u_add(FPU_REG *arg1, FPU_REG *arg2, FPU_REG *answ,
10  *                                                int control_w)
11  *
12  *
13  * Copyright (C) 1992,1993,1994
14  *                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,
15  *                       Australia.  E-mail   billm@vaxc.cc.monash.edu.au
16  * All rights reserved.
17  *
18  * This copyright notice covers the redistribution and use of the
19  * FPU emulator developed by W. Metzenthen. It covers only its use
20  * in the 386BSD, FreeBSD and NetBSD operating systems. Any other
21  * use is not permitted under this copyright.
22  *
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions
25  * are met:
26  * 1. Redistributions of source code must retain the above copyright
27  *    notice, this list of conditions and the following disclaimer.
28  * 2. Redistributions in binary form must include information specifying
29  *    that source code for the emulator is freely available and include
30  *    either:
31  *      a) an offer to provide the source code for a nominal distribution
32  *         fee, or
33  *      b) list at least two alternative methods whereby the source
34  *         can be obtained, e.g. a publically accessible bulletin board
35  *         and an anonymous ftp site from which the software can be
36  *         downloaded.
37  * 3. All advertising materials specifically mentioning features or use of
38  *    this emulator must acknowledge that it was developed by W. Metzenthen.
39  * 4. The name of W. Metzenthen may not be used to endorse or promote
40  *    products derived from this software without specific prior written
41  *    permission.
42  *
43  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
44  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
45  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
46  * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
47  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
48  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
49  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
50  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
51  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
52  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
53  *
54  *
55  * The purpose of this copyright, based upon the Berkeley copyright, is to
56  * ensure that the covered software remains freely available to everyone.
57  *
58  * The software (with necessary differences) is also available, but under
59  * the terms of the GNU copyleft, for the Linux operating system and for
60  * the djgpp ms-dos extender.
61  *
62  * W. Metzenthen   June 1994.
63  *
64  *
65  * $FreeBSD: src/sys/gnu/i386/fpemul/reg_u_add.s,v 1.9 1999/08/28 00:42:57 peter Exp $
66  * $DragonFly: src/sys/i386/gnu/fpemul/Attic/reg_u_add.s,v 1.3 2003/07/31 12:37:39 hmp Exp $
67  *
68  */
69
70
71 /*
72  |    Kernel addition routine reg_u_add(reg *arg1, reg *arg2, reg *answ).
73  |    Takes two valid reg f.p. numbers (TW_Valid), which are
74  |    treated as unsigned numbers,
75  |    and returns their sum as a TW_Valid or TW_S f.p. number.
76  |    The returned number is normalized.
77  |    Basic checks are performed if PARANOID is defined.
78  */
79
80 #include <gnu/i386/fpemul/fpu_asm.h>
81
82 .text
83 ENTRY(reg_u_add)
84         pushl   %ebp
85         movl    %esp,%ebp
86 /*      subl    $16,%esp*/
87         pushl   %esi
88         pushl   %edi
89         pushl   %ebx
90
91         movl    PARAM1,%esi             /* source 1 */
92         movl    PARAM2,%edi             /* source 2 */
93
94 #ifdef DENORM_OPERAND
95         cmpl    EXP_UNDER,EXP(%esi)
96         jg      xOp1_not_denorm
97
98         call    denormal_operand
99         orl     %eax,%eax
100         jnz     FPU_Arith_exit
101
102 xOp1_not_denorm:
103         cmpl    EXP_UNDER,EXP(%edi)
104         jg      xOp2_not_denorm
105
106         call    denormal_operand
107         orl     %eax,%eax
108         jnz     FPU_Arith_exit
109
110 xOp2_not_denorm:
111 #endif DENORM_OPERAND
112
113 /*      xorl    %ecx,%ecx*/
114         movl    EXP(%esi),%ecx
115         subl    EXP(%edi),%ecx          /* exp1 - exp2 */
116 /*      jnc     L_arg1_larger*/
117         jge     L_arg1_larger
118
119         /* num1 is smaller */
120         movl    SIGL(%esi),%ebx
121         movl    SIGH(%esi),%eax
122
123         movl    %edi,%esi
124         negw    %cx
125         jmp     L_accum_loaded
126
127 L_arg1_larger:
128         /* num1 has larger or equal exponent */
129         movl    SIGL(%edi),%ebx
130         movl    SIGH(%edi),%eax
131
132 L_accum_loaded:
133         movl    PARAM3,%edi             /* destination */
134         movb    SIGN(%esi),%dl
135         movb    %dl,SIGN(%edi)          /* Copy the sign from the first arg */
136
137
138         movl    EXP(%esi),%edx
139         movl    %edx,EXP(%edi)  /* Copy exponent to destination */
140
141         xorl    %edx,%edx               /* clear the extension */
142
143 #ifdef PARANOID
144         testl   $0x80000000,%eax
145         je      L_bugged
146
147         testl   $0x80000000,SIGH(%esi)
148         je      L_bugged
149 #endif PARANOID
150
151 /* The number to be shifted is in %eax:%ebx:%edx*/
152         cmpw    $32,%cx         /* shrd only works for 0..31 bits */
153         jnc     L_more_than_31
154
155 /* less than 32 bits */
156         shrd    %cl,%ebx,%edx
157         shrd    %cl,%eax,%ebx
158         shr     %cl,%eax
159         jmp     L_shift_done
160
161 L_more_than_31:
162         cmpw    $64,%cx
163         jnc     L_more_than_63
164
165         subb    $32,%cl
166         jz      L_exactly_32
167
168         shrd    %cl,%eax,%edx
169         shr     %cl,%eax
170         orl     %ebx,%ebx
171         jz      L_more_31_no_low        /* none of the lowest bits is set*/
172
173         orl     $1,%edx                 /* record the fact in the extension*/
174
175 L_more_31_no_low:
176         movl    %eax,%ebx
177         xorl    %eax,%eax
178         jmp     L_shift_done
179
180 L_exactly_32:
181         movl    %ebx,%edx
182         movl    %eax,%ebx
183         xorl    %eax,%eax
184         jmp     L_shift_done
185
186 L_more_than_63:
187         cmpw    $65,%cx
188         jnc     L_more_than_64
189
190         movl    %eax,%edx
191         orl     %ebx,%ebx
192         jz      L_more_63_no_low
193
194         orl     $1,%edx
195         jmp     L_more_63_no_low
196
197 L_more_than_64:
198         movl    $1,%edx         /* The shifted nr always at least one '1'*/
199
200 L_more_63_no_low:
201         xorl    %ebx,%ebx
202         xorl    %eax,%eax
203
204 L_shift_done:
205         /* Now do the addition */
206         addl    SIGL(%esi),%ebx
207         adcl    SIGH(%esi),%eax
208         jnc     L_round_the_result
209
210         /* Overflow, adjust the result */
211         rcrl    $1,%eax
212         rcrl    $1,%ebx
213         rcrl    $1,%edx
214         jnc     L_no_bit_lost
215
216         orl     $1,%edx
217
218 L_no_bit_lost:
219         incl    EXP(%edi)
220
221 L_round_the_result:
222         jmp     FPU_round       /* Round the result*/
223
224
225
226 #ifdef PARANOID
227 /* If we ever get here then we have problems! */
228 L_bugged:
229         pushl   EX_INTERNAL|0x201
230         call    EXCEPTION
231         pop     %ebx
232         jmp     L_exit
233 #endif PARANOID
234
235
236 L_exit:
237         popl    %ebx
238         popl    %edi
239         popl    %esi
240         leave
241         ret