1 .file "reg_u_sub.S"
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 #include "exception.h"
29 #include "fpu_asm.h"
30 #include "control_w.h"
31
32
33 .text
34 .align 2,144
35 .globl _reg_u_sub
36 _reg_u_sub:
37 pushl %ebp
38 movl %esp,%ebp
39 pushl %esi
40 pushl %edi
41 pushl %ebx
42
43 movl PARAM1,%esi
44 movl PARAM2,%edi
45
46
47 movl EXP(%esi),%ecx
48 subl EXP(%edi),%ecx
49
50 #ifdef PARANOID
51
52
53 js L_bugged_1
54
55 testl $0x80000000,SIGH(%edi)
56 je L_bugged_2
57
58 testl $0x80000000,SIGH(%esi)
59 je L_bugged_2
60 #endif PARANOID
61
62
63
64
65
66 movl SIGH(%edi),%eax
67 movl SIGL(%edi),%ebx
68
69 movl PARAM3,%edi
70 movl EXP(%esi),%edx
71 movl %edx,EXP(%edi)
72 movb SIGN(%esi),%dl
73 movb %dl,SIGN(%edi)
74
75 xorl %edx,%edx
76
77
78
79
80
81
82 L_shift_r:
83 cmpl $32,%ecx
84 jnc L_more_than_31
85
86
87 shrd %cl,%ebx,%edx
88 shrd %cl,%eax,%ebx
89 shr %cl,%eax
90 jmp L_shift_done
91
92 L_more_than_31:
93 cmpl $64,%ecx
94 jnc L_more_than_63
95
96 subb $32,%cl
97 jz L_exactly_32
98
99 shrd %cl,%eax,%edx
100 shr %cl,%eax
101 orl %ebx,%ebx
102 jz L_more_31_no_low
103
104 orl $1,%edx
105
106 L_more_31_no_low:
107 movl %eax,%ebx
108 xorl %eax,%eax
109 jmp L_shift_done
110
111 L_exactly_32:
112 movl %ebx,%edx
113 movl %eax,%ebx
114 xorl %eax,%eax
115 jmp L_shift_done
116
117 L_more_than_63:
118 cmpw $65,%cx
119 jnc L_more_than_64
120
121
122 movl %eax,%edx
123 orl %ebx,%ebx
124 jz L_more_63_no_low
125
126 orl $1,%edx
127 jmp L_more_63_no_low
128
129 L_more_than_64:
130 jne L_more_than_65
131
132
133
134 movl %eax,%edx
135 rcrl %edx
136 jnc L_shift_65_nc
137
138 orl $1,%edx
139 jmp L_more_63_no_low
140
141 L_shift_65_nc:
142 orl %ebx,%ebx
143 jz L_more_63_no_low
144
145 orl $1,%edx
146 jmp L_more_63_no_low
147
148 L_more_than_65:
149 movl $1,%edx
150
151 L_more_63_no_low:
152 xorl %ebx,%ebx
153 xorl %eax,%eax
154
155 L_shift_done:
156 L_subtr:
157
158
159
160 xorl %ecx,%ecx
161 subl %edx,%ecx
162 movl %ecx,%edx
163 movl SIGL(%esi),%ecx
164 sbbl %ebx,%ecx
165 movl %ecx,%ebx
166 movl SIGH(%esi),%ecx
167 sbbl %eax,%ecx
168 movl %ecx,%eax
169
170 #ifdef PARANOID
171
172 jc L_bugged
173 #endif PARANOID
174
175
176
177
178 testl $0x80000000,%eax
179 jnz L_round
180
181 orl %eax,%eax
182 jnz L_shift_1
183
184 orl %ebx,%ebx
185 jnz L_shift_32
186
187
188
189
190
191
192
193 cmpl $0x80000000,%edx
194 jnz L_must_be_zero
195
196
197 subl $64,EXP(%edi)
198 movl %edx,%eax
199 jmp L_store
200
201 L_must_be_zero:
202 #ifdef PARANOID
203 orl %edx,%edx
204 jnz L_bugged_3
205 #endif PARANOID
206
207
208 movb TW_Zero,TAG(%edi)
209 movl $0,EXP(%edi)
210 movl $0,SIGL(%edi)
211 movl $0,SIGH(%edi)
212 jmp L_exit
213
214 L_shift_32:
215 movl %ebx,%eax
216 movl %edx,%ebx
217 movl $0,%edx
218 subl $32,EXP(%edi)
219
220
221 L_shift_1:
222 bsrl %eax,%ecx
223 subl $31,%ecx
224 negl %ecx
225 shld %cl,%ebx,%eax
226 shld %cl,%edx,%ebx
227 shl %cl,%edx
228 subl %ecx,EXP(%edi)
229
230 L_round:
231 jmp FPU_round
232
233
234 #ifdef PARANOID
235 L_bugged_1:
236 pushl EX_INTERNAL|0x206
237 call EXCEPTION
238 pop %ebx
239 jmp L_exit
240
241 L_bugged_2:
242 pushl EX_INTERNAL|0x209
243 call EXCEPTION
244 pop %ebx
245 jmp L_exit
246
247 L_bugged_3:
248 pushl EX_INTERNAL|0x210
249 call EXCEPTION
250 pop %ebx
251 jmp L_exit
252
253 L_bugged_4:
254 pushl EX_INTERNAL|0x211
255 call EXCEPTION
256 pop %ebx
257 jmp L_exit
258
259 L_bugged:
260 pushl EX_INTERNAL|0x212
261 call EXCEPTION
262 pop %ebx
263 jmp L_exit
264 #endif PARANOID
265
266
267 L_store:
268
269
270
271 movl %eax,SIGH(%edi)
272 movl %ebx,SIGL(%edi)
273
274 movb TW_Valid,TAG(%edi)
275
276 cmpl EXP_UNDER,EXP(%edi)
277 jle L_underflow
278
279 L_exit:
280 popl %ebx
281 popl %edi
282 popl %esi
283 leave
284 ret
285
286
287 L_underflow:
288 push %edi
289 call _arith_underflow
290 pop %ebx
291 jmp L_exit
292