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 pushl %ebx
90 pushl %esi
91 call _real_2op_NaN
92 jmp LDiv_exit
93
94
95 L_zero_zero:
96 L_inf_inf:
97 pushl %edi
98 call _arith_invalid
99 jmp LDiv_exit
100
101 L_no_NaN_arg:
102 cmpb TW_Infinity,TAG(%esi)
103 jne L_arg1_not_inf
104
105 cmpb TW_Infinity,TAG(%ebx)
106 je L_inf_inf
107
108 cmpb TW_Valid,TAG(%ebx)
109 je L_inf_valid
110
111 #ifdef PARANOID
112
113 cmpb TW_Zero,TAG(%ebx)
114 ja L_unknown_tags
115 #endif PARANOID
116
117
118 jmp L_copy_arg1
119
120 L_inf_valid:
121 #ifdef DENORM_OPERAND
122 cmpl EXP_UNDER,EXP(%ebx)
123 jg L_copy_arg1
124
125 call _denormal_operand
126 orl %eax,%eax
127 jnz FPU_Arith_exit
128 #endif DENORM_OPERAND
129
130 jmp L_copy_arg1
131
132 L_arg1_not_inf:
133 cmpb TW_Zero,TAG(%ebx)
134 jne L_arg2_not_zero
135
136 cmpb TW_Zero,TAG(%esi)
137 je L_zero_zero
138
139 #ifdef PARANOID
140
141 cmpb TW_Valid,TAG(%esi)
142 ja L_unknown_tags
143 #endif PARANOID
144
145
146 pushl %edi
147 movb SIGN(%esi),%al
148 xorb SIGN(%ebx),%al
149 pushl %eax
150 call _divide_by_zero
151 jmp LDiv_exit
152
153 L_arg2_not_zero:
154 cmpb TW_Infinity,TAG(%ebx)
155 jne L_arg2_not_inf
156
157 #ifdef DENORM_OPERAND
158 cmpb TW_Valid,TAG(%esi)
159 jne L_return_zero
160
161 cmpl EXP_UNDER,EXP(%esi)
162 jg L_return_zero
163
164 call _denormal_operand
165 orl %eax,%eax
166 jnz FPU_Arith_exit
167 #endif DENORM_OPERAND
168
169 jmp L_return_zero
170
171 L_arg2_not_inf:
172
173 #ifdef PARANOID
174 cmpb TW_Zero,TAG(%esi)
175 jne L_unknown_tags
176 #endif PARANOID
177
178
179
180 #ifdef DENORM_OPERAND
181 cmpl EXP_UNDER,EXP(%ebx)
182 jg L_copy_arg1
183
184 call _denormal_operand
185 orl %eax,%eax
186 jnz FPU_Arith_exit
187 #endif DENORM_OPERAND
188
189 L_copy_arg1:
190 movb TAG(%esi),%ax
191 movb %ax,TAG(%edi)
192 movl EXP(%esi),%eax
193 movl %eax,EXP(%edi)
194 movl SIGL(%esi),%eax
195 movl %eax,SIGL(%edi)
196 movl SIGH(%esi),%eax
197 movl %eax,SIGH(%edi)
198
199 movb SIGN(%esi),%cl
200 cmpb %cl,SIGN(%ebx)
201 jne LDiv_negative_result
202
203 movb SIGN_POS,SIGN(%edi)
204 jmp LDiv_exit
205
206 LDiv_set_result_sign:
207 movb SIGN(%esi),%cl
208 cmpb %cl,SIGN(%edi)
209 jne LDiv_negative_result
210
211 movb SIGN_POS,SIGN(%ebx)
212 jmp LDiv_exit
213
214 LDiv_negative_result:
215 movb SIGN_NEG,SIGN(%edi)
216
217 LDiv_exit:
218 leal -12(%ebp),%esp
219
220 popl %ebx
221 popl %edi
222 popl %esi
223 leave
224 ret
225
226
227 L_return_zero:
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