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