1 .file "reg_div.S"
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 #include "exception.h"
18 #include "fpu_asm.h"
19
20
21 .text
22 .align 2
23
24 .globl _reg_div
25 _reg_div:
26 pushl %ebp
27 movl %esp,%ebp
28 #ifndef NON_REENTRANT_FPU
29 subl $28,%esp
30 #endif NON_REENTRANT_FPU
31
32 pushl %esi
33 pushl %edi
34 pushl %ebx
35
36 movl PARAM1,%esi
37 movl PARAM2,%ebx
38 movl PARAM3,%edi
39
40 movb TAG(%esi),%al
41 orb TAG(%ebx),%al
42
43 jne L_div_special
44
45 #ifdef DENORM_OPERAND
46
47 cmpl EXP_UNDER,EXP(%esi)
48 jg xL_arg1_not_denormal
49
50 call _denormal_operand
51 orl %eax,%eax
52 jnz fpu_Arith_exit
53
54 xL_arg1_not_denormal:
55 cmpl EXP_UNDER,EXP(%ebx)
56 jg xL_arg2_not_denormal
57
58 call _denormal_operand
59 orl %eax,%eax
60 jnz fpu_Arith_exit
61
62 xL_arg2_not_denormal:
63 #endif DENORM_OPERAND
64
65
66 movb TW_Valid,TAG(%edi)
67
68 movb SIGN(%esi),%cl
69 cmpb %cl,SIGN(%ebx)
70 setne (%edi)
71
72 movl EXP(%esi),%edx
73 movl EXP(%ebx),%eax
74 subl %eax,%edx
75 addl EXP_BIAS,%edx
76 movl %edx,EXP(%edi)
77
78 jmp _divide_kernel
79
80
81
82 L_div_special:
83 cmpb TW_NaN,TAG(%esi)
84 je L_arg1_NaN
85
86 cmpb TW_NaN,TAG(%ebx)
87 jne L_no_NaN_arg
88
89
90 L_arg1_NaN:
91 L_arg2_NaN:
92 pushl %edi
93 pushl %esi
94 pushl %ebx
95 call _real_2op_NaN
96 jmp LDiv_exit
97
98
99 L_zero_zero:
100 L_inf_inf:
101 pushl %edi
102 call _arith_invalid
103 jmp LDiv_exit
104
105 L_no_NaN_arg:
106 cmpb TW_Infinity,TAG(%esi)
107 jne L_arg1_not_inf
108
109 cmpb TW_Infinity,TAG(%ebx)
110 je L_inf_inf
111
112 cmpb TW_Valid,TAG(%ebx)
113 je L_inf_valid
114
115 #ifdef PARANOID
116
117 cmpb TW_Zero,TAG(%ebx)
118 ja L_unknown_tags
119 #endif PARANOID
120
121
122 jmp L_copy_arg1
123
124 L_inf_valid:
125 #ifdef DENORM_OPERAND
126 cmpl EXP_UNDER,EXP(%ebx)
127 jg L_copy_arg1
128
129 call _denormal_operand
130 orl %eax,%eax
131 jnz fpu_Arith_exit
132 #endif DENORM_OPERAND
133
134 jmp L_copy_arg1
135
136 L_arg1_not_inf:
137 cmpb TW_Zero,TAG(%ebx)
138 jne L_arg2_not_zero
139
140 cmpb TW_Zero,TAG(%esi)
141 je L_zero_zero
142
143 #ifdef PARANOID
144
145 cmpb TW_Valid,TAG(%esi)
146 ja L_unknown_tags
147 #endif PARANOID
148
149
150 pushl %edi
151 movb SIGN(%esi),%al
152 xorb SIGN(%ebx),%al
153 pushl %eax
154 call _divide_by_zero
155 jmp LDiv_exit
156
157 L_arg2_not_zero:
158 cmpb TW_Infinity,TAG(%ebx)
159 jne L_arg2_not_inf
160
161 #ifdef DENORM_OPERAND
162 cmpb TW_Valid,TAG(%esi)
163 jne L_return_zero
164
165 cmpl EXP_UNDER,EXP(%esi)
166 jg L_return_zero
167
168 call _denormal_operand
169 orl %eax,%eax
170 jnz fpu_Arith_exit
171 #endif DENORM_OPERAND
172
173 jmp L_return_zero
174
175 L_arg2_not_inf:
176
177 #ifdef PARANOID
178 cmpb TW_Zero,TAG(%esi)
179 jne L_unknown_tags
180 #endif PARANOID
181
182
183
184 #ifdef DENORM_OPERAND
185 cmpl EXP_UNDER,EXP(%ebx)
186 jg L_copy_arg1
187
188 call _denormal_operand
189 orl %eax,%eax
190 jnz fpu_Arith_exit
191 #endif DENORM_OPERAND
192
193 L_copy_arg1:
194 movb TAG(%esi),%ax
195 movb %ax,TAG(%edi)
196 movl EXP(%esi),%eax
197 movl %eax,EXP(%edi)
198 movl SIGL(%esi),%eax
199 movl %eax,SIGL(%edi)
200 movl SIGH(%esi),%eax
201 movl %eax,SIGH(%edi)
202
203 LDiv_set_result_sign:
204 movb SIGN(%esi),%cl
205 cmpb %cl,SIGN(%ebx)
206 jne LDiv_negative_result
207
208 movb SIGN_POS,SIGN(%edi)
209 xorl %eax,%eax
210 jmp LDiv_exit
211
212 LDiv_negative_result:
213 movb SIGN_NEG,SIGN(%edi)
214 xorl %eax,%eax
215
216 LDiv_exit:
217 #ifndef NON_REENTRANT_FPU
218 leal -40(%ebp),%esp
219 #else
220 leal -12(%ebp),%esp
221 #endif NON_REENTRANT_FPU
222
223 popl %ebx
224 popl %edi
225 popl %esi
226 leave
227 ret
228
229
230 L_return_zero:
231 xorl %eax,%eax
232 movl %eax,SIGH(%edi)
233 movl %eax,SIGL(%edi)
234 movl EXP_UNDER,EXP(%edi)
235 movb TW_Zero,TAG(%edi)
236 jmp LDiv_set_result_sign
237
238 #ifdef PARANOID
239 L_unknown_tags:
240 pushl EX_INTERNAL | 0x208
241 call EXCEPTION
242
243
244 movl _CONST_QNaN,%eax
245 movl %eax,(%edi)
246 movl _CONST_QNaN+4,%eax
247 movl %eax,SIGL(%edi)
248 movl _CONST_QNaN+8,%eax
249 movl %eax,SIGH(%edi)
250 jmp LDiv_exit
251 #endif PARANOID