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 .text
21 .align 2
22
23 .globl _reg_div
24 _reg_div:
25 pushl %ebp
26 movl %esp,%ebp
27
28 pushl %esi
29 pushl %edi
30 pushl %ebx
31
32 movl PARAM1,%esi
33 movl PARAM2,%ebx
34 movl PARAM3,%edi
35
36 movb TAG(%esi),%al
37 orb TAG(%ebx),%al
38
39 jne L_div_special
40
41 #ifdef DENORM_OPERAND
42
43 cmpl EXP_UNDER,EXP(%esi)
44 jg xL_arg1_not_denormal
45
46 call _denormal_operand
47 orl %eax,%eax
48 jnz FPU_Arith_exit
49
50 xL_arg1_not_denormal:
51 cmpl EXP_UNDER,EXP(%ebx)
52 jg xL_arg2_not_denormal
53
54 call _denormal_operand
55 orl %eax,%eax
56 jnz FPU_Arith_exit
57
58 xL_arg2_not_denormal:
59 #endif DENORM_OPERAND
60
61
62 movb TW_Valid,TAG(%edi)
63
64 movb SIGN(%esi),%cl
65 cmpb %cl,SIGN(%ebx)
66 setne (%edi)
67
68 movl EXP(%esi),%edx
69 movl EXP(%ebx),%eax
70 subl %eax,%edx
71 addl EXP_BIAS,%edx
72 movl %edx,EXP(%edi)
73
74 jmp _divide_kernel
75
76
77
78 L_div_special:
79 cmpb TW_NaN,TAG(%esi)
80 je L_arg1_NaN
81
82 cmpb TW_NaN,TAG(%ebx)
83 jne L_no_NaN_arg
84
85
86 L_arg1_NaN:
87 L_arg2_NaN:
88 pushl %edi
89
90 pushl %esi
91 pushl %ebx
92 call _real_2op_NaN
93 jmp LDiv_exit
94
95
96 L_zero_zero:
97 L_inf_inf:
98 pushl %edi
99 call _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 _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 _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 _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 _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 leal -12(%ebp),%esp
215
216 popl %ebx
217 popl %edi
218 popl %esi
219 leave
220 ret
221
222
223 L_return_zero:
224 xorl %eax,%eax
225 movl %eax,SIGH(%edi)
226 movl %eax,SIGL(%edi)
227 movl EXP_UNDER,EXP(%edi)
228 movb TW_Zero,TAG(%edi)
229 jmp LDiv_set_result_sign
230
231 #ifdef PARANOID
232 L_unknown_tags:
233 push EX_INTERNAL | 0x208
234 call EXCEPTION
235
236
237 movl _CONST_QNaN,%eax
238 movl %eax,(%edi)
239 movl _CONST_QNaN+4,%eax
240 movl %eax,SIGL(%edi)
241 movl _CONST_QNaN+8,%eax
242 movl %eax,SIGH(%edi)
243 jmp LDiv_exit
244 #endif PARANOID