1 .file "reg_round.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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53 #include "fpu_asm.h"
54 #include "fpu_emu.h"
55 #include "exception.h"
56 #include "control_w.h"
57
58
59 .text
60 .align 2,144
61 .globl FPU_round
62 .globl FPU_round_sqrt
63
64 FPU_round:
65
66 movl PARAM4,%ecx
67
68 FPU_round_sqrt:
69 movl %ecx,%esi
70 andl CW_PC,%ecx
71 cmpl PR_64_BITS,%ecx
72 je LRound_To_64
73
74 cmpl PR_53_BITS,%ecx
75 je LRound_To_53
76
77 cmpl PR_24_BITS,%ecx
78 je LRound_To_24
79
80 #ifdef PARANOID
81 jmp L_bugged
82 #endif PARANOID
83
84
85 LRound_To_24:
86 movl %esi,%ecx
87 andl CW_RC,%ecx
88 cmpl RC_RND,%ecx
89 je LRound_nearest_24
90
91 cmpl RC_CHOP,%ecx
92 je LTruncate_24
93
94 cmpl RC_UP,%ecx
95 je LUp_24
96
97 cmpl RC_DOWN,%ecx
98 je LDown_24
99
100 #ifdef PARANOID
101 jmp L_bugged
102 #endif PARANOID
103
104 LUp_24:
105 cmpb SIGN_POS,SIGN(%edi)
106 je LUp_24_pos
107
108 movl %eax,%ecx
109 andl $0x000000ff,%ecx
110 orl %ebx,%ecx
111 orl %edx,%ecx
112 jnz LTruncate_24
113 jmp L_store
114
115 LUp_24_pos:
116 movl %eax,%ecx
117 andl $0x000000ff,%ecx
118 orl %ebx,%ecx
119 orl %edx,%ecx
120 jnz LDo_24_round_up
121 jmp L_store
122
123 LDown_24:
124 cmpb SIGN_POS,SIGN(%edi)
125 je LDown_24_pos
126
127 movl %eax,%ecx
128 andl $0x000000ff,%ecx
129 orl %ebx,%ecx
130 orl %edx,%ecx
131 jnz LDo_24_round_up
132 jmp L_store
133
134 LDown_24_pos:
135 movl %eax,%ecx
136 andl $0x000000ff,%ecx
137 orl %ebx,%ecx
138 orl %edx,%ecx
139 jnz LTruncate_24
140 jmp L_store
141
142 LRound_nearest_24:
143
144 movl %eax,%ecx
145 andl $0x000000ff,%ecx
146 cmpl $0x00000080,%ecx
147 jc LTruncate_24
148
149 jne LGreater_Half_24
150
151
152 orl %ebx,%ebx
153 jne LGreater_Half_24
154
155 orl %edx,%edx
156 jne LGreater_Half_24
157
158
159 testl $0x00000100,%eax
160 jz LTruncate_24
161
162 LGreater_Half_24:
163 LDo_24_round_up:
164 andl $0xffffff00,%eax
165 xorl %ebx,%ebx
166 addl $0x00000100,%eax
167 jmp LCheck_Round_Overflow
168
169 LTruncate_24:
170 andl $0xffffff00,%eax
171 xorl %ebx,%ebx
172 jmp L_store
173
174
175 LRound_To_53:
176 movl %esi,%ecx
177 andl CW_RC,%ecx
178 cmpl RC_RND,%ecx
179 je LRound_nearest_53
180
181 cmpl RC_CHOP,%ecx
182 je LTruncate_53
183
184 cmpl RC_UP,%ecx
185 je LUp_53
186
187 cmpl RC_DOWN,%ecx
188 je LDown_53
189
190 #ifdef PARANOID
191 jmp L_bugged
192 #endif PARANOID
193
194 LUp_53:
195 cmpb SIGN_POS,SIGN(%edi)
196 je LUp_53_pos
197
198 movl %ebx,%ecx
199 andl $0x000007ff,%ecx
200 orl %edx,%ecx
201 jnz LTruncate_53
202 jmp L_store
203
204 LUp_53_pos:
205 movl %ebx,%ecx
206 andl $0x000007ff,%ecx
207 orl %edx,%ecx
208 jnz LDo_53_round_up
209 jmp L_store
210
211 LDown_53:
212 cmpb SIGN_POS,SIGN(%edi)
213 je LDown_53_pos
214
215 movl %ebx,%ecx
216 andl $0x000007ff,%ecx
217 orl %edx,%ecx
218 jnz LDo_53_round_up
219 jmp L_store
220
221 LDown_53_pos:
222 movl %ebx,%ecx
223 andl $0x000007ff,%ecx
224 orl %edx,%ecx
225 jnz LTruncate_53
226 jmp L_store
227
228 LRound_nearest_53:
229
230 movl %ebx,%ecx
231 andl $0x000007ff,%ecx
232 cmpl $0x00000400,%ecx
233 jc LTruncate_53
234
235 jne LGreater_Half_53
236
237
238 orl %edx,%edx
239 jne LGreater_Half_53
240
241
242 testl $0x00000800,%ebx
243 jz LTruncate_53
244
245 LGreater_Half_53:
246 LDo_53_round_up:
247 andl $0xfffff800,%ebx
248 addl $0x00000800,%ebx
249 adcl $0,%eax
250 jmp LCheck_Round_Overflow
251
252 LTruncate_53:
253 andl $0xfffff800,%ebx
254 jmp L_store
255
256
257 LRound_To_64:
258 movl %esi,%ecx
259 andl CW_RC,%ecx
260 cmpl RC_RND,%ecx
261 je LRound_nearest_64
262
263 cmpl RC_CHOP,%ecx
264 je LTruncate_64
265
266 cmpl RC_UP,%ecx
267 je LUp_64
268
269 cmpl RC_DOWN,%ecx
270 je LDown_64
271
272 #ifdef PARANOID
273 jmp L_bugged
274 #endif PARANOID
275
276 LUp_64:
277 cmpb SIGN_POS,SIGN(%edi)
278 je LUp_64_pos
279
280 orl %edx,%edx
281 jnz LTruncate_64
282 jmp L_store
283
284 LUp_64_pos:
285 orl %edx,%edx
286 jnz LDo_64_round_up
287 jmp L_store
288
289 LDown_64:
290 cmpb SIGN_POS,SIGN(%edi)
291 je LDown_64_pos
292
293 orl %edx,%edx
294 jnz LDo_64_round_up
295 jmp L_store
296
297 LDown_64_pos:
298 orl %edx,%edx
299 jnz LTruncate_64
300 jmp L_store
301
302 LRound_nearest_64:
303 cmpl $0x80000000,%edx
304 jc LTruncate_64
305
306 jne LDo_64_round_up
307
308
309 testb $1,%ebx
310 jz LTruncate_64
311
312 LDo_64_round_up:
313 addl $1,%ebx
314 adcl $0,%eax
315
316 LCheck_Round_Overflow:
317 jnc L_store
318
319
320 rcrl $1,%eax
321 rcrl $1,%ebx
322 incl EXP(%edi)
323
324 LTruncate_64:
325 L_store:
326
327 movl %eax,SIGH(%edi)
328 movl %ebx,SIGL(%edi)
329
330 movb TW_Valid,TAG(%edi)
331
332
333 cmpl EXP_OVER,EXP(%edi)
334 jge L_overflow
335
336 cmpl EXP_UNDER,EXP(%edi)
337 jle L_underflow
338
339 L_exit:
340 popl %ebx
341 popl %edi
342 popl %esi
343 leave
344 ret
345
346
347
348 L_overflow:
349 push %edi
350 call _arith_overflow
351 pop %edi
352 jmp L_exit
353
354
355 L_underflow:
356 pushl %edi
357 call _arith_underflow
358 popl %edi
359 jmp L_exit
360
361
362 #ifdef PARANOID
363
364 L_bugged:
365 pushl EX_INTERNAL|0x201
366 call EXCEPTION
367 pop %ebx
368 jmp L_exit
369 #endif PARANOID