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