]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/mips/mips/fp.S
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / sys / mips / mips / fp.S
1 /*      $OpenBSD: fp.S,v 1.2 1998/03/16 09:03:31 pefo Exp $     */
2 /*-
3  * Copyright (c) 1992, 1993
4  *      The Regents of the University of California.  All rights reserved.
5  *
6  * This code is derived from software contributed to Berkeley by
7  * Ralph Campbell.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 4. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  *      from: @(#)fp.s  8.1 (Berkeley) 6/10/93
34  *      JNPR: fp.S,v 1.1 2006/08/07 05:38:57 katta
35  * $FreeBSD$
36  */
37
38 /*
39  * Standard header stuff.
40  */
41
42 #include <machine/asm.h>
43 #include <machine/regnum.h>
44 #include <machine/cpuregs.h>
45
46 #include "assym.s"
47
48 #define SEXP_INF        0xff
49 #define DEXP_INF        0x7ff
50 #define SEXP_BIAS       127
51 #define DEXP_BIAS       1023
52 #define SEXP_MIN        -126
53 #define DEXP_MIN        -1022
54 #define SEXP_MAX        127
55 #define DEXP_MAX        1023
56 #define WEXP_MAX        30              /* maximum unbiased exponent for int */
57 #define WEXP_MIN        -1              /* minimum unbiased exponent for int */
58 #define SFRAC_BITS      23
59 #define DFRAC_BITS      52
60 #define SIMPL_ONE       0x00800000
61 #define DIMPL_ONE       0x00100000
62 #define SLEAD_ZEROS     31 - 23
63 #define DLEAD_ZEROS     31 - 20
64 #define STICKYBIT       1
65 #define GUARDBIT        0x80000000
66 #define SSIGNAL_NAN     0x00400000
67 #define DSIGNAL_NAN     0x00080000
68 #define SQUIET_NAN      0x003fffff
69 #define DQUIET_NAN0     0x0007ffff
70 #define DQUIET_NAN1     0xffffffff
71 #define INT_MIN         0x80000000
72 #define INT_MAX         0x7fffffff
73
74 #define COND_UNORDERED  0x1
75 #define COND_EQUAL      0x2
76 #define COND_LESS       0x4
77 #define COND_SIGNAL     0x8
78
79 /*----------------------------------------------------------------------------
80  *
81  * MipsEmulateFP --
82  *
83  *      Emulate unimplemented floating point operations.
84  *      This routine should only be called by MipsFPInterrupt().
85  *
86  *      MipsEmulateFP(instr)
87  *              unsigned instr;
88  *
89  * Results:
90  *      None.
91  *
92  * Side effects:
93  *      Floating point registers are modified according to instruction.
94  *
95  *----------------------------------------------------------------------------
96  */
97 NON_LEAF(MipsEmulateFP, CALLFRAME_SIZ, ra)
98         subu    sp, sp, CALLFRAME_SIZ
99         sw      ra, CALLFRAME_RA(sp)
100 /*
101  * Decode the FMT field (bits 24-21) and FUNCTION field (bits 5-0).
102  */
103         srl     v0, a0, 21 - 2                  # get FMT field
104         and     v0, v0, 0xF << 2                # mask FMT field
105         and     v1, a0, 0x3F                    # mask FUNC field
106         sll     v1, v1, 5                       # align for table lookup
107         bgt     v0, 4 << 2, ill                 # illegal format
108
109         or      v1, v1, v0
110         cfc1    a1, MIPS_FPU_CSR                # get exception register
111         lw      a3, func_fmt_tbl(v1)            # switch on FUNC & FMT
112         and     a1, a1, ~MIPS_FPU_EXCEPTION_UNIMPL # clear exception
113         ctc1    a1, MIPS_FPU_CSR
114         j       a3
115
116         .rdata
117 func_fmt_tbl:
118         .word   add_s           # 0
119         .word   add_d           # 0
120         .word   ill             # 0
121         .word   ill             # 0
122         .word   ill             # 0
123         .word   ill             # 0
124         .word   ill             # 0
125         .word   ill             # 0
126         .word   sub_s           # 1
127         .word   sub_d           # 1
128         .word   ill             # 1
129         .word   ill             # 1
130         .word   ill             # 1
131         .word   ill             # 1
132         .word   ill             # 1
133         .word   ill             # 1
134         .word   mul_s           # 2
135         .word   mul_d           # 2
136         .word   ill             # 2
137         .word   ill             # 2
138         .word   ill             # 2
139         .word   ill             # 2
140         .word   ill             # 2
141         .word   ill             # 2
142         .word   div_s           # 3
143         .word   div_d           # 3
144         .word   ill             # 3
145         .word   ill             # 3
146         .word   ill             # 3
147         .word   ill             # 3
148         .word   ill             # 3
149         .word   ill             # 3
150         .word   ill             # 4
151         .word   ill             # 4
152         .word   ill             # 4
153         .word   ill             # 4
154         .word   ill             # 4
155         .word   ill             # 4
156         .word   ill             # 4
157         .word   ill             # 4
158         .word   abs_s           # 5
159         .word   abs_d           # 5
160         .word   ill             # 5
161         .word   ill             # 5
162         .word   ill             # 5
163         .word   ill             # 5
164         .word   ill             # 5
165         .word   ill             # 5
166         .word   mov_s           # 6
167         .word   mov_d           # 6
168         .word   ill             # 6
169         .word   ill             # 6
170         .word   ill             # 6
171         .word   ill             # 6
172         .word   ill             # 6
173         .word   ill             # 6
174         .word   neg_s           # 7
175         .word   neg_d           # 7
176         .word   ill             # 7
177         .word   ill             # 7
178         .word   ill             # 7
179         .word   ill             # 7
180         .word   ill             # 7
181         .word   ill             # 7
182         .word   ill             # 8
183         .word   ill             # 8
184         .word   ill             # 8
185         .word   ill             # 8
186         .word   ill             # 8
187         .word   ill             # 8
188         .word   ill             # 8
189         .word   ill             # 8
190         .word   ill             # 9
191         .word   ill             # 9
192         .word   ill             # 9
193         .word   ill             # 9
194         .word   ill             # 9
195         .word   ill             # 9
196         .word   ill             # 9
197         .word   ill             # 9
198         .word   ill             # 10
199         .word   ill             # 10
200         .word   ill             # 10
201         .word   ill             # 10
202         .word   ill             # 10
203         .word   ill             # 10
204         .word   ill             # 10
205         .word   ill             # 10
206         .word   ill             # 11
207         .word   ill             # 11
208         .word   ill             # 11
209         .word   ill             # 11
210         .word   ill             # 11
211         .word   ill             # 11
212         .word   ill             # 11
213         .word   ill             # 11
214         .word   ill             # 12
215         .word   ill             # 12
216         .word   ill             # 12
217         .word   ill             # 12
218         .word   ill             # 12
219         .word   ill             # 12
220         .word   ill             # 12
221         .word   ill             # 12
222         .word   ill             # 13
223         .word   ill             # 13
224         .word   ill             # 13
225         .word   ill             # 13
226         .word   ill             # 13
227         .word   ill             # 13
228         .word   ill             # 13
229         .word   ill             # 13
230         .word   ill             # 14
231         .word   ill             # 14
232         .word   ill             # 14
233         .word   ill             # 14
234         .word   ill             # 14
235         .word   ill             # 14
236         .word   ill             # 14
237         .word   ill             # 14
238         .word   ill             # 15
239         .word   ill             # 15
240         .word   ill             # 15
241         .word   ill             # 15
242         .word   ill             # 15
243         .word   ill             # 15
244         .word   ill             # 15
245         .word   ill             # 15
246         .word   ill             # 16
247         .word   ill             # 16
248         .word   ill             # 16
249         .word   ill             # 16
250         .word   ill             # 16
251         .word   ill             # 16
252         .word   ill             # 16
253         .word   ill             # 16
254         .word   ill             # 17
255         .word   ill             # 17
256         .word   ill             # 17
257         .word   ill             # 17
258         .word   ill             # 17
259         .word   ill             # 17
260         .word   ill             # 17
261         .word   ill             # 17
262         .word   ill             # 18
263         .word   ill             # 18
264         .word   ill             # 18
265         .word   ill             # 18
266         .word   ill             # 18
267         .word   ill             # 18
268         .word   ill             # 18
269         .word   ill             # 18
270         .word   ill             # 19
271         .word   ill             # 19
272         .word   ill             # 19
273         .word   ill             # 19
274         .word   ill             # 19
275         .word   ill             # 19
276         .word   ill             # 19
277         .word   ill             # 19
278         .word   ill             # 20
279         .word   ill             # 20
280         .word   ill             # 20
281         .word   ill             # 20
282         .word   ill             # 20
283         .word   ill             # 20
284         .word   ill             # 20
285         .word   ill             # 20
286         .word   ill             # 21
287         .word   ill             # 21
288         .word   ill             # 21
289         .word   ill             # 21
290         .word   ill             # 21
291         .word   ill             # 21
292         .word   ill             # 21
293         .word   ill             # 21
294         .word   ill             # 22
295         .word   ill             # 22
296         .word   ill             # 22
297         .word   ill             # 22
298         .word   ill             # 22
299         .word   ill             # 22
300         .word   ill             # 22
301         .word   ill             # 22
302         .word   ill             # 23
303         .word   ill             # 23
304         .word   ill             # 23
305         .word   ill             # 23
306         .word   ill             # 23
307         .word   ill             # 23
308         .word   ill             # 23
309         .word   ill             # 23
310         .word   ill             # 24
311         .word   ill             # 24
312         .word   ill             # 24
313         .word   ill             # 24
314         .word   ill             # 24
315         .word   ill             # 24
316         .word   ill             # 24
317         .word   ill             # 24
318         .word   ill             # 25
319         .word   ill             # 25
320         .word   ill             # 25
321         .word   ill             # 25
322         .word   ill             # 25
323         .word   ill             # 25
324         .word   ill             # 25
325         .word   ill             # 25
326         .word   ill             # 26
327         .word   ill             # 26
328         .word   ill             # 26
329         .word   ill             # 26
330         .word   ill             # 26
331         .word   ill             # 26
332         .word   ill             # 26
333         .word   ill             # 26
334         .word   ill             # 27
335         .word   ill             # 27
336         .word   ill             # 27
337         .word   ill             # 27
338         .word   ill             # 27
339         .word   ill             # 27
340         .word   ill             # 27
341         .word   ill             # 27
342         .word   ill             # 28
343         .word   ill             # 28
344         .word   ill             # 28
345         .word   ill             # 28
346         .word   ill             # 28
347         .word   ill             # 28
348         .word   ill             # 28
349         .word   ill             # 28
350         .word   ill             # 29
351         .word   ill             # 29
352         .word   ill             # 29
353         .word   ill             # 29
354         .word   ill             # 29
355         .word   ill             # 29
356         .word   ill             # 29
357         .word   ill             # 29
358         .word   ill             # 30
359         .word   ill             # 30
360         .word   ill             # 30
361         .word   ill             # 30
362         .word   ill             # 30
363         .word   ill             # 30
364         .word   ill             # 30
365         .word   ill             # 30
366         .word   ill             # 31
367         .word   ill             # 31
368         .word   ill             # 31
369         .word   ill             # 31
370         .word   ill             # 31
371         .word   ill             # 31
372         .word   ill             # 31
373         .word   ill             # 31
374         .word   ill             # 32
375         .word   cvt_s_d         # 32
376         .word   ill             # 32
377         .word   ill             # 32
378         .word   cvt_s_w         # 32
379         .word   ill             # 32
380         .word   ill             # 32
381         .word   ill             # 32
382         .word   cvt_d_s         # 33
383         .word   ill             # 33
384         .word   ill             # 33
385         .word   ill             # 33
386         .word   cvt_d_w         # 33
387         .word   ill             # 33
388         .word   ill             # 33
389         .word   ill             # 33
390         .word   ill             # 34
391         .word   ill             # 34
392         .word   ill             # 34
393         .word   ill             # 34
394         .word   ill             # 34
395         .word   ill             # 34
396         .word   ill             # 34
397         .word   ill             # 34
398         .word   ill             # 35
399         .word   ill             # 35
400         .word   ill             # 35
401         .word   ill             # 35
402         .word   ill             # 35
403         .word   ill             # 35
404         .word   ill             # 35
405         .word   ill             # 35
406         .word   cvt_w_s         # 36
407         .word   cvt_w_d         # 36
408         .word   ill             # 36
409         .word   ill             # 36
410         .word   ill             # 36
411         .word   ill             # 36
412         .word   ill             # 36
413         .word   ill             # 36
414         .word   ill             # 37
415         .word   ill             # 37
416         .word   ill             # 37
417         .word   ill             # 37
418         .word   ill             # 37
419         .word   ill             # 37
420         .word   ill             # 37
421         .word   ill             # 37
422         .word   ill             # 38
423         .word   ill             # 38
424         .word   ill             # 38
425         .word   ill             # 38
426         .word   ill             # 38
427         .word   ill             # 38
428         .word   ill             # 38
429         .word   ill             # 38
430         .word   ill             # 39
431         .word   ill             # 39
432         .word   ill             # 39
433         .word   ill             # 39
434         .word   ill             # 39
435         .word   ill             # 39
436         .word   ill             # 39
437         .word   ill             # 39
438         .word   ill             # 40
439         .word   ill             # 40
440         .word   ill             # 40
441         .word   ill             # 40
442         .word   ill             # 40
443         .word   ill             # 40
444         .word   ill             # 40
445         .word   ill             # 40
446         .word   ill             # 41
447         .word   ill             # 41
448         .word   ill             # 41
449         .word   ill             # 41
450         .word   ill             # 41
451         .word   ill             # 41
452         .word   ill             # 41
453         .word   ill             # 41
454         .word   ill             # 42
455         .word   ill             # 42
456         .word   ill             # 42
457         .word   ill             # 42
458         .word   ill             # 42
459         .word   ill             # 42
460         .word   ill             # 42
461         .word   ill             # 42
462         .word   ill             # 43
463         .word   ill             # 43
464         .word   ill             # 43
465         .word   ill             # 43
466         .word   ill             # 43
467         .word   ill             # 43
468         .word   ill             # 43
469         .word   ill             # 43
470         .word   ill             # 44
471         .word   ill             # 44
472         .word   ill             # 44
473         .word   ill             # 44
474         .word   ill             # 44
475         .word   ill             # 44
476         .word   ill             # 44
477         .word   ill             # 44
478         .word   ill             # 45
479         .word   ill             # 45
480         .word   ill             # 45
481         .word   ill             # 45
482         .word   ill             # 45
483         .word   ill             # 45
484         .word   ill             # 45
485         .word   ill             # 45
486         .word   ill             # 46
487         .word   ill             # 46
488         .word   ill             # 46
489         .word   ill             # 46
490         .word   ill             # 46
491         .word   ill             # 46
492         .word   ill             # 46
493         .word   ill             # 46
494         .word   ill             # 47
495         .word   ill             # 47
496         .word   ill             # 47
497         .word   ill             # 47
498         .word   ill             # 47
499         .word   ill             # 47
500         .word   ill             # 47
501         .word   ill             # 47
502         .word   cmp_s           # 48
503         .word   cmp_d           # 48
504         .word   ill             # 48
505         .word   ill             # 48
506         .word   ill             # 48
507         .word   ill             # 48
508         .word   ill             # 48
509         .word   ill             # 48
510         .word   cmp_s           # 49
511         .word   cmp_d           # 49
512         .word   ill             # 49
513         .word   ill             # 49
514         .word   ill             # 49
515         .word   ill             # 49
516         .word   ill             # 49
517         .word   ill             # 49
518         .word   cmp_s           # 50
519         .word   cmp_d           # 50
520         .word   ill             # 50
521         .word   ill             # 50
522         .word   ill             # 50
523         .word   ill             # 50
524         .word   ill             # 50
525         .word   ill             # 50
526         .word   cmp_s           # 51
527         .word   cmp_d           # 51
528         .word   ill             # 51
529         .word   ill             # 51
530         .word   ill             # 51
531         .word   ill             # 51
532         .word   ill             # 51
533         .word   ill             # 51
534         .word   cmp_s           # 52
535         .word   cmp_d           # 52
536         .word   ill             # 52
537         .word   ill             # 52
538         .word   ill             # 52
539         .word   ill             # 52
540         .word   ill             # 52
541         .word   ill             # 52
542         .word   cmp_s           # 53
543         .word   cmp_d           # 53
544         .word   ill             # 53
545         .word   ill             # 53
546         .word   ill             # 53
547         .word   ill             # 53
548         .word   ill             # 53
549         .word   ill             # 53
550         .word   cmp_s           # 54
551         .word   cmp_d           # 54
552         .word   ill             # 54
553         .word   ill             # 54
554         .word   ill             # 54
555         .word   ill             # 54
556         .word   ill             # 54
557         .word   ill             # 54
558         .word   cmp_s           # 55
559         .word   cmp_d           # 55
560         .word   ill             # 55
561         .word   ill             # 55
562         .word   ill             # 55
563         .word   ill             # 55
564         .word   ill             # 55
565         .word   ill             # 55
566         .word   cmp_s           # 56
567         .word   cmp_d           # 56
568         .word   ill             # 56
569         .word   ill             # 56
570         .word   ill             # 56
571         .word   ill             # 56
572         .word   ill             # 56
573         .word   ill             # 56
574         .word   cmp_s           # 57
575         .word   cmp_d           # 57
576         .word   ill             # 57
577         .word   ill             # 57
578         .word   ill             # 57
579         .word   ill             # 57
580         .word   ill             # 57
581         .word   ill             # 57
582         .word   cmp_s           # 58
583         .word   cmp_d           # 58
584         .word   ill             # 58
585         .word   ill             # 58
586         .word   ill             # 58
587         .word   ill             # 58
588         .word   ill             # 58
589         .word   ill             # 58
590         .word   cmp_s           # 59
591         .word   cmp_d           # 59
592         .word   ill             # 59
593         .word   ill             # 59
594         .word   ill             # 59
595         .word   ill             # 59
596         .word   ill             # 59
597         .word   ill             # 59
598         .word   cmp_s           # 60
599         .word   cmp_d           # 60
600         .word   ill             # 60
601         .word   ill             # 60
602         .word   ill             # 60
603         .word   ill             # 60
604         .word   ill             # 60
605         .word   ill             # 60
606         .word   cmp_s           # 61
607         .word   cmp_d           # 61
608         .word   ill             # 61
609         .word   ill             # 61
610         .word   ill             # 61
611         .word   ill             # 61
612         .word   ill             # 61
613         .word   ill             # 61
614         .word   cmp_s           # 62
615         .word   cmp_d           # 62
616         .word   ill             # 62
617         .word   ill             # 62
618         .word   ill             # 62
619         .word   ill             # 62
620         .word   ill             # 62
621         .word   ill             # 62
622         .word   cmp_s           # 63
623         .word   cmp_d           # 63
624         .word   ill             # 63
625         .word   ill             # 63
626         .word   ill             # 63
627         .word   ill             # 63
628         .word   ill             # 63
629         .word   ill             # 63
630         .text
631
632 /*
633  * Single precision subtract.
634  */
635 sub_s:
636         jal     get_ft_fs_s
637         xor     ta0, ta0, 1                     # negate FT sign bit
638         b       add_sub_s
639 /*
640  * Single precision add.
641  */
642 add_s:
643         jal     get_ft_fs_s
644 add_sub_s:
645         bne     t1, SEXP_INF, 1f                # is FS an infinity?
646         bne     ta1, SEXP_INF, result_fs_s      # if FT is not inf, result=FS
647         bne     t2, zero, result_fs_s           # if FS is NAN, result is FS
648         bne     ta2, zero, result_ft_s          # if FT is NAN, result is FT
649         bne     t0, ta0, invalid_s              # both infinities same sign?
650         b       result_fs_s                     # result is in FS
651 1:
652         beq     ta1, SEXP_INF, result_ft_s      # if FT is inf, result=FT
653         bne     t1, zero, 4f                    # is FS a denormalized num?
654         beq     t2, zero, 3f                    # is FS zero?
655         bne     ta1, zero, 2f                   # is FT a denormalized num?
656         beq     ta2, zero, result_fs_s          # FT is zero, result=FS
657         jal     renorm_fs_s
658         jal     renorm_ft_s
659         b       5f
660 2:
661         jal     renorm_fs_s
662         subu    ta1, ta1, SEXP_BIAS             # unbias FT exponent
663         or      ta2, ta2, SIMPL_ONE             # set implied one bit
664         b       5f
665 3:
666         bne     ta1, zero, result_ft_s          # if FT != 0, result=FT
667         bne     ta2, zero, result_ft_s
668         and     v0, a1, MIPS_FPU_ROUNDING_BITS  # get rounding mode
669         bne     v0, MIPS_FPU_ROUND_RM, 1f       # round to -infinity?
670         or      t0, t0, ta0                     # compute result sign
671         b       result_fs_s
672 1:
673         and     t0, t0, ta0                     # compute result sign
674         b       result_fs_s
675 4:
676         bne     ta1, zero, 2f                   # is FT a denormalized num?
677         beq     ta2, zero, result_fs_s          # FT is zero, result=FS
678         subu    t1, t1, SEXP_BIAS               # unbias FS exponent
679         or      t2, t2, SIMPL_ONE               # set implied one bit
680         jal     renorm_ft_s
681         b       5f
682 2:
683         subu    t1, t1, SEXP_BIAS               # unbias FS exponent
684         or      t2, t2, SIMPL_ONE               # set implied one bit
685         subu    ta1, ta1, SEXP_BIAS             # unbias FT exponent
686         or      ta2, ta2, SIMPL_ONE             # set implied one bit
687 /*
688  * Perform the addition.
689  */
690 5:
691         move    t8, zero                        # no shifted bits (sticky reg)
692         beq     t1, ta1, 4f                     # no shift needed
693         subu    v0, t1, ta1                     # v0 = difference of exponents
694         move    v1, v0                          # v1 = abs(difference)
695         bge     v0, zero, 1f
696         negu    v1
697 1:
698         ble     v1, SFRAC_BITS+2, 2f            # is difference too great?
699         li      t8, STICKYBIT                   # set the sticky bit
700         bge     v0, zero, 1f                    # check which exp is larger
701         move    t1, ta1                         # result exp is FTs
702         move    t2, zero                        # FSs fraction shifted is zero
703         b       4f
704 1:
705         move    ta2, zero                       # FTs fraction shifted is zero
706         b       4f
707 2:
708         li      t9, 32                          # compute 32 - abs(exp diff)
709         subu    t9, t9, v1
710         bgt     v0, zero, 3f                    # if FS > FT, shift FTs frac
711         move    t1, ta1                         # FT > FS, result exp is FTs
712         sll     t8, t2, t9                      # save bits shifted out
713         srl     t2, t2, v1                      # shift FSs fraction
714         b       4f
715 3:
716         sll     t8, ta2, t9                     # save bits shifted out
717         srl     ta2, ta2, v1                    # shift FTs fraction
718 4:
719         bne     t0, ta0, 1f                     # if signs differ, subtract
720         addu    t2, t2, ta2                     # add fractions
721         b       norm_s
722 1:
723         blt     t2, ta2, 3f                     # subtract larger from smaller
724         bne     t2, ta2, 2f                     # if same, result=0
725         move    t1, zero                        # result=0
726         move    t2, zero
727         and     v0, a1, MIPS_FPU_ROUNDING_BITS  # get rounding mode
728         bne     v0, MIPS_FPU_ROUND_RM, 1f       # round to -infinity?
729         or      t0, t0, ta0                     # compute result sign
730         b       result_fs_s
731 1:
732         and     t0, t0, ta0                     # compute result sign
733         b       result_fs_s
734 2:
735         sltu    t9, zero, t8                    # compute t2:zero - ta2:t8
736         subu    t8, zero, t8
737         subu    t2, t2, ta2                     # subtract fractions
738         subu    t2, t2, t9                      # subtract barrow
739         b       norm_s
740 3:
741         move    t0, ta0                         # sign of result = FTs
742         sltu    t9, zero, t8                    # compute ta2:zero - t2:t8
743         subu    t8, zero, t8
744         subu    t2, ta2, t2                     # subtract fractions
745         subu    t2, t2, t9                      # subtract barrow
746         b       norm_s
747
748 /*
749  * Double precision subtract.
750  */
751 sub_d:
752         jal     get_ft_fs_d
753         xor     ta0, ta0, 1                     # negate sign bit
754         b       add_sub_d
755 /*
756  * Double precision add.
757  */
758 add_d:
759         jal     get_ft_fs_d
760 add_sub_d:
761         bne     t1, DEXP_INF, 1f                # is FS an infinity?
762         bne     ta1, DEXP_INF, result_fs_d      # if FT is not inf, result=FS
763         bne     t2, zero, result_fs_d           # if FS is NAN, result is FS
764         bne     t3, zero, result_fs_d
765         bne     ta2, zero, result_ft_d          # if FT is NAN, result is FT
766         bne     ta3, zero, result_ft_d
767         bne     t0, ta0, invalid_d              # both infinities same sign?
768         b       result_fs_d                     # result is in FS
769 1:
770         beq     ta1, DEXP_INF, result_ft_d      # if FT is inf, result=FT
771         bne     t1, zero, 4f                    # is FS a denormalized num?
772         bne     t2, zero, 1f                    # is FS zero?
773         beq     t3, zero, 3f
774 1:
775         bne     ta1, zero, 2f                   # is FT a denormalized num?
776         bne     ta2, zero, 1f
777         beq     ta3, zero, result_fs_d          # FT is zero, result=FS
778 1:
779         jal     renorm_fs_d
780         jal     renorm_ft_d
781         b       5f
782 2:
783         jal     renorm_fs_d
784         subu    ta1, ta1, DEXP_BIAS             # unbias FT exponent
785         or      ta2, ta2, DIMPL_ONE             # set implied one bit
786         b       5f
787 3:
788         bne     ta1, zero, result_ft_d          # if FT != 0, result=FT
789         bne     ta2, zero, result_ft_d
790         bne     ta3, zero, result_ft_d
791         and     v0, a1, MIPS_FPU_ROUNDING_BITS  # get rounding mode
792         bne     v0, MIPS_FPU_ROUND_RM, 1f       # round to -infinity?
793         or      t0, t0, ta0                     # compute result sign
794         b       result_fs_d
795 1:
796         and     t0, t0, ta0                     # compute result sign
797         b       result_fs_d
798 4:
799         bne     ta1, zero, 2f                   # is FT a denormalized num?
800         bne     ta2, zero, 1f
801         beq     ta3, zero, result_fs_d          # FT is zero, result=FS
802 1:
803         subu    t1, t1, DEXP_BIAS               # unbias FS exponent
804         or      t2, t2, DIMPL_ONE               # set implied one bit
805         jal     renorm_ft_d
806         b       5f
807 2:
808         subu    t1, t1, DEXP_BIAS               # unbias FS exponent
809         or      t2, t2, DIMPL_ONE               # set implied one bit
810         subu    ta1, ta1, DEXP_BIAS             # unbias FT exponent
811         or      ta2, ta2, DIMPL_ONE             # set implied one bit
812 /*
813  * Perform the addition.
814  */
815 5:
816         move    t8, zero                        # no shifted bits (sticky reg)
817         beq     t1, ta1, 4f                     # no shift needed
818         subu    v0, t1, ta1                     # v0 = difference of exponents
819         move    v1, v0                          # v1 = abs(difference)
820         bge     v0, zero, 1f
821         negu    v1
822 1:
823         ble     v1, DFRAC_BITS+2, 2f            # is difference too great?
824         li      t8, STICKYBIT                   # set the sticky bit
825         bge     v0, zero, 1f                    # check which exp is larger
826         move    t1, ta1                         # result exp is FTs
827         move    t2, zero                        # FSs fraction shifted is zero
828         move    t3, zero
829         b       4f
830 1:
831         move    ta2, zero                       # FTs fraction shifted is zero
832         move    ta3, zero
833         b       4f
834 2:
835         li      t9, 32
836         bge     v0, zero, 3f                    # if FS > FT, shift FTs frac
837         move    t1, ta1                         # FT > FS, result exp is FTs
838         blt     v1, t9, 1f                      # shift right by < 32?
839         subu    v1, v1, t9
840         subu    t9, t9, v1
841         sll     t8, t2, t9                      # save bits shifted out
842         sltu    t9, zero, t3                    # dont lose any one bits
843         or      t8, t8, t9                      # save sticky bit
844         srl     t3, t2, v1                      # shift FSs fraction
845         move    t2, zero
846         b       4f
847 1:
848         subu    t9, t9, v1
849         sll     t8, t3, t9                      # save bits shifted out
850         srl     t3, t3, v1                      # shift FSs fraction
851         sll     t9, t2, t9                      # save bits shifted out of t2
852         or      t3, t3, t9                      # and put into t3
853         srl     t2, t2, v1
854         b       4f
855 3:
856         blt     v1, t9, 1f                      # shift right by < 32?
857         subu    v1, v1, t9
858         subu    t9, t9, v1
859         sll     t8, ta2, t9                     # save bits shifted out
860         srl     ta3, ta2, v1                    # shift FTs fraction
861         move    ta2, zero
862         b       4f
863 1:
864         subu    t9, t9, v1
865         sll     t8, ta3, t9                     # save bits shifted out
866         srl     ta3, ta3, v1                    # shift FTs fraction
867         sll     t9, ta2, t9                     # save bits shifted out of t2
868         or      ta3, ta3, t9                    # and put into t3
869         srl     ta2, ta2, v1
870 4:
871         bne     t0, ta0, 1f                     # if signs differ, subtract
872         addu    t3, t3, ta3                     # add fractions
873         sltu    t9, t3, ta3                     # compute carry
874         addu    t2, t2, ta2                     # add fractions
875         addu    t2, t2, t9                      # add carry
876         b       norm_d
877 1:
878         blt     t2, ta2, 3f                     # subtract larger from smaller
879         bne     t2, ta2, 2f
880         bltu    t3, ta3, 3f
881         bne     t3, ta3, 2f                     # if same, result=0
882         move    t1, zero                        # result=0
883         move    t2, zero
884         move    t3, zero
885         and     v0, a1, MIPS_FPU_ROUNDING_BITS  # get rounding mode
886         bne     v0, MIPS_FPU_ROUND_RM, 1f       # round to -infinity?
887         or      t0, t0, ta0                     # compute result sign
888         b       result_fs_d
889 1:
890         and     t0, t0, ta0                     # compute result sign
891         b       result_fs_d
892 2:
893         beq     t8, zero, 1f                    # compute t2:t3:zero - ta2:ta3:t8
894         subu    t8, zero, t8
895         sltu    v0, t3, 1                       # compute barrow out
896         subu    t3, t3, 1                       # subtract barrow
897         subu    t2, t2, v0
898 1:
899         sltu    v0, t3, ta3
900         subu    t3, t3, ta3                     # subtract fractions
901         subu    t2, t2, ta2                     # subtract fractions
902         subu    t2, t2, v0                      # subtract barrow
903         b       norm_d
904 3:
905         move    t0, ta0                         # sign of result = FTs
906         beq     t8, zero, 1f                    # compute ta2:ta3:zero - t2:t3:t8
907         subu    t8, zero, t8
908         sltu    v0, ta3, 1                      # compute barrow out
909         subu    ta3, ta3, 1                     # subtract barrow
910         subu    ta2, ta2, v0
911 1:
912         sltu    v0, ta3, t3
913         subu    t3, ta3, t3                     # subtract fractions
914         subu    t2, ta2, t2                     # subtract fractions
915         subu    t2, t2, v0                      # subtract barrow
916         b       norm_d
917
918 /*
919  * Single precision multiply.
920  */
921 mul_s:
922         jal     get_ft_fs_s
923         xor     t0, t0, ta0                     # compute sign of result
924         move    ta0, t0
925         bne     t1, SEXP_INF, 2f                # is FS an infinity?
926         bne     t2, zero, result_fs_s           # if FS is a NAN, result=FS
927         bne     ta1, SEXP_INF, 1f               # FS is inf, is FT an infinity?
928         bne     ta2, zero, result_ft_s          # if FT is a NAN, result=FT
929         b       result_fs_s                     # result is infinity
930 1:
931         bne     ta1, zero, result_fs_s          # inf * zero? if no, result=FS
932         bne     ta2, zero, result_fs_s
933         b       invalid_s                       # infinity * zero is invalid
934 2:
935         bne     ta1, SEXP_INF, 1f               # FS != inf, is FT an infinity?
936         bne     t1, zero, result_ft_s           # zero * inf? if no, result=FT
937         bne     t2, zero, result_ft_s
938         bne     ta2, zero, result_ft_s          # if FT is a NAN, result=FT
939         b       invalid_s                       # zero * infinity is invalid
940 1:
941         bne     t1, zero, 1f                    # is FS zero?
942         beq     t2, zero, result_fs_s           # result is zero
943         jal     renorm_fs_s
944         b       2f
945 1:
946         subu    t1, t1, SEXP_BIAS               # unbias FS exponent
947         or      t2, t2, SIMPL_ONE               # set implied one bit
948 2:
949         bne     ta1, zero, 1f                   # is FT zero?
950         beq     ta2, zero, result_ft_s          # result is zero
951         jal     renorm_ft_s
952         b       2f
953 1:
954         subu    ta1, ta1, SEXP_BIAS             # unbias FT exponent
955         or      ta2, ta2, SIMPL_ONE             # set implied one bit
956 2:
957         addu    t1, t1, ta1                     # compute result exponent
958         addu    t1, t1, 9                       # account for binary point
959         multu   t2, ta2                         # multiply fractions
960         mflo    t8
961         mfhi    t2
962         b       norm_s
963
964 /*
965  * Double precision multiply.
966  */
967 mul_d:
968         jal     get_ft_fs_d
969         xor     t0, t0, ta0                     # compute sign of result
970         move    ta0, t0
971         bne     t1, DEXP_INF, 2f                # is FS an infinity?
972         bne     t2, zero, result_fs_d           # if FS is a NAN, result=FS
973         bne     t3, zero, result_fs_d
974         bne     ta1, DEXP_INF, 1f               # FS is inf, is FT an infinity?
975         bne     ta2, zero, result_ft_d          # if FT is a NAN, result=FT
976         bne     ta3, zero, result_ft_d
977         b       result_fs_d                     # result is infinity
978 1:
979         bne     ta1, zero, result_fs_d          # inf * zero? if no, result=FS
980         bne     ta2, zero, result_fs_d
981         bne     ta3, zero, result_fs_d
982         b       invalid_d                       # infinity * zero is invalid
983 2:
984         bne     ta1, DEXP_INF, 1f               # FS != inf, is FT an infinity?
985         bne     t1, zero, result_ft_d           # zero * inf? if no, result=FT
986         bne     t2, zero, result_ft_d           # if FS is a NAN, result=FS
987         bne     t3, zero, result_ft_d
988         bne     ta2, zero, result_ft_d          # if FT is a NAN, result=FT
989         bne     ta3, zero, result_ft_d
990         b       invalid_d                       # zero * infinity is invalid
991 1:
992         bne     t1, zero, 2f                    # is FS zero?
993         bne     t2, zero, 1f
994         beq     t3, zero, result_fs_d           # result is zero
995 1:
996         jal     renorm_fs_d
997         b       3f
998 2:
999         subu    t1, t1, DEXP_BIAS               # unbias FS exponent
1000         or      t2, t2, DIMPL_ONE               # set implied one bit
1001 3:
1002         bne     ta1, zero, 2f                   # is FT zero?
1003         bne     ta2, zero, 1f
1004         beq     ta3, zero, result_ft_d          # result is zero
1005 1:
1006         jal     renorm_ft_d
1007         b       3f
1008 2:
1009         subu    ta1, ta1, DEXP_BIAS             # unbias FT exponent
1010         or      ta2, ta2, DIMPL_ONE             # set implied one bit
1011 3:
1012         addu    t1, t1, ta1                     # compute result exponent
1013         addu    t1, t1, 12                      # ???
1014         multu   t3, ta3                         # multiply fractions (low * low)
1015         move    ta0, t2                         # free up t2,t3 for result
1016         move    ta1, t3
1017         mflo    a3                              # save low order bits
1018         mfhi    t8
1019         not     v0, t8
1020         multu   ta0, ta3                        # multiply FS(high) * FT(low)
1021         mflo    v1
1022         mfhi    t3                              # init low result
1023         sltu    v0, v0, v1                      # compute carry
1024         addu    t8, v1
1025         multu   ta1, ta2                        # multiply FS(low) * FT(high)
1026         addu    t3, t3, v0                      # add carry
1027         not     v0, t8
1028         mflo    v1
1029         mfhi    t2
1030         sltu    v0, v0, v1
1031         addu    t8, v1
1032         multu   ta0, ta2                        # multiply FS(high) * FT(high)
1033         addu    t3, v0
1034         not     v1, t3
1035         sltu    v1, v1, t2
1036         addu    t3, t2
1037         not     v0, t3
1038         mfhi    t2
1039         addu    t2, v1
1040         mflo    v1
1041         sltu    v0, v0, v1
1042         addu    t2, v0
1043         addu    t3, v1
1044         sltu    a3, zero, a3                    # reduce t8,a3 to just t8
1045         or      t8, a3
1046         b       norm_d
1047
1048 /*
1049  * Single precision divide.
1050  */
1051 div_s:
1052         jal     get_ft_fs_s
1053         xor     t0, t0, ta0                     # compute sign of result
1054         move    ta0, t0
1055         bne     t1, SEXP_INF, 1f                # is FS an infinity?
1056         bne     t2, zero, result_fs_s           # if FS is NAN, result is FS
1057         bne     ta1, SEXP_INF, result_fs_s      # is FT an infinity?
1058         bne     ta2, zero, result_ft_s          # if FT is NAN, result is FT
1059         b       invalid_s                       # infinity/infinity is invalid
1060 1:
1061         bne     ta1, SEXP_INF, 1f               # is FT an infinity?
1062         bne     ta2, zero, result_ft_s          # if FT is NAN, result is FT
1063         move    t1, zero                        # x / infinity is zero
1064         move    t2, zero
1065         b       result_fs_s
1066 1:
1067         bne     t1, zero, 2f                    # is FS zero?
1068         bne     t2, zero, 1f
1069         bne     ta1, zero, result_fs_s          # FS=zero, is FT zero?
1070         beq     ta2, zero, invalid_s            # 0 / 0
1071         b       result_fs_s                     # result = zero
1072 1:
1073         jal     renorm_fs_s
1074         b       3f
1075 2:
1076         subu    t1, t1, SEXP_BIAS               # unbias FS exponent
1077         or      t2, t2, SIMPL_ONE               # set implied one bit
1078 3:
1079         bne     ta1, zero, 2f                   # is FT zero?
1080         bne     ta2, zero, 1f
1081         or      a1, a1, MIPS_FPU_EXCEPTION_DIV0 | MIPS_FPU_STICKY_DIV0
1082         and     v0, a1, MIPS_FPU_ENABLE_DIV0    # trap enabled?
1083         bne     v0, zero, fpe_trap
1084         ctc1    a1, MIPS_FPU_CSR                # save exceptions
1085         li      t1, SEXP_INF                    # result is infinity
1086         move    t2, zero
1087         b       result_fs_s
1088 1:
1089         jal     renorm_ft_s
1090         b       3f
1091 2:
1092         subu    ta1, ta1, SEXP_BIAS             # unbias FT exponent
1093         or      ta2, ta2, SIMPL_ONE             # set implied one bit
1094 3:
1095         subu    t1, t1, ta1                     # compute exponent
1096         subu    t1, t1, 3                       # compensate for result position
1097         li      v0, SFRAC_BITS+3                # number of bits to divide
1098         move    t8, t2                          # init dividend
1099         move    t2, zero                        # init result
1100 1:
1101         bltu    t8, ta2, 3f                     # is dividend >= divisor?
1102 2:
1103         subu    t8, t8, ta2                     # subtract divisor from dividend
1104         or      t2, t2, 1                       # remember that we did
1105         bne     t8, zero, 3f                    # if not done, continue
1106         sll     t2, t2, v0                      # shift result to final position
1107         b       norm_s
1108 3:
1109         sll     t8, t8, 1                       # shift dividend
1110         sll     t2, t2, 1                       # shift result
1111         subu    v0, v0, 1                       # are we done?
1112         bne     v0, zero, 1b                    # no, continue
1113         b       norm_s
1114
1115 /*
1116  * Double precision divide.
1117  */
1118 div_d:
1119         jal     get_ft_fs_d
1120         xor     t0, t0, ta0                     # compute sign of result
1121         move    ta0, t0
1122         bne     t1, DEXP_INF, 1f                # is FS an infinity?
1123         bne     t2, zero, result_fs_d           # if FS is NAN, result is FS
1124         bne     t3, zero, result_fs_d
1125         bne     ta1, DEXP_INF, result_fs_d      # is FT an infinity?
1126         bne     ta2, zero, result_ft_d          # if FT is NAN, result is FT
1127         bne     ta3, zero, result_ft_d
1128         b       invalid_d                       # infinity/infinity is invalid
1129 1:
1130         bne     ta1, DEXP_INF, 1f               # is FT an infinity?
1131         bne     ta2, zero, result_ft_d          # if FT is NAN, result is FT
1132         bne     ta3, zero, result_ft_d
1133         move    t1, zero                        # x / infinity is zero
1134         move    t2, zero
1135         move    t3, zero
1136         b       result_fs_d
1137 1:
1138         bne     t1, zero, 2f                    # is FS zero?
1139         bne     t2, zero, 1f
1140         bne     t3, zero, 1f
1141         bne     ta1, zero, result_fs_d          # FS=zero, is FT zero?
1142         bne     ta2, zero, result_fs_d
1143         beq     ta3, zero, invalid_d            # 0 / 0
1144         b       result_fs_d                     # result = zero
1145 1:
1146         jal     renorm_fs_d
1147         b       3f
1148 2:
1149         subu    t1, t1, DEXP_BIAS               # unbias FS exponent
1150         or      t2, t2, DIMPL_ONE               # set implied one bit
1151 3:
1152         bne     ta1, zero, 2f                   # is FT zero?
1153         bne     ta2, zero, 1f
1154         bne     ta3, zero, 1f
1155         or      a1, a1, MIPS_FPU_EXCEPTION_DIV0 | MIPS_FPU_STICKY_DIV0
1156         and     v0, a1, MIPS_FPU_ENABLE_DIV0    # trap enabled?
1157         bne     v0, zero, fpe_trap
1158         ctc1    a1, MIPS_FPU_CSR                # Save exceptions
1159         li      t1, DEXP_INF                    # result is infinity
1160         move    t2, zero
1161         move    t3, zero
1162         b       result_fs_d
1163 1:
1164         jal     renorm_ft_d
1165         b       3f
1166 2:
1167         subu    ta1, ta1, DEXP_BIAS             # unbias FT exponent
1168         or      ta2, ta2, DIMPL_ONE             # set implied one bit
1169 3:
1170         subu    t1, t1, ta1                     # compute exponent
1171         subu    t1, t1, 3                       # compensate for result position
1172         li      v0, DFRAC_BITS+3                # number of bits to divide
1173         move    t8, t2                          # init dividend
1174         move    t9, t3
1175         move    t2, zero                        # init result
1176         move    t3, zero
1177 1:
1178         bltu    t8, ta2, 3f                     # is dividend >= divisor?
1179         bne     t8, ta2, 2f
1180         bltu    t9, ta3, 3f
1181 2:
1182         sltu    v1, t9, ta3                     # subtract divisor from dividend
1183         subu    t9, t9, ta3
1184         subu    t8, t8, ta2
1185         subu    t8, t8, v1
1186         or      t3, t3, 1                       # remember that we did
1187         bne     t8, zero, 3f                    # if not done, continue
1188         bne     t9, zero, 3f
1189         li      v1, 32                          # shift result to final position
1190         blt     v0, v1, 2f                      # shift < 32 bits?
1191         subu    v0, v0, v1                      # shift by > 32 bits
1192         sll     t2, t3, v0                      # shift upper part
1193         move    t3, zero
1194         b       norm_d
1195 2:
1196         subu    v1, v1, v0                      # shift by < 32 bits
1197         sll     t2, t2, v0                      # shift upper part
1198         srl     t9, t3, v1                      # save bits shifted out
1199         or      t2, t2, t9                      # and put into upper part
1200         sll     t3, t3, v0
1201         b       norm_d
1202 3:
1203         sll     t8, t8, 1                       # shift dividend
1204         srl     v1, t9, 31                      # save bit shifted out
1205         or      t8, t8, v1                      # and put into upper part
1206         sll     t9, t9, 1
1207         sll     t2, t2, 1                       # shift result
1208         srl     v1, t3, 31                      # save bit shifted out
1209         or      t2, t2, v1                      # and put into upper part
1210         sll     t3, t3, 1
1211         subu    v0, v0, 1                       # are we done?
1212         bne     v0, zero, 1b                    # no, continue
1213         sltu    v0, zero, t9                    # be sure to save any one bits
1214         or      t8, t8, v0                      # from the lower remainder
1215         b       norm_d
1216
1217 /*
1218  * Single precision absolute value.
1219  */
1220 abs_s:
1221         jal     get_fs_s
1222         move    t0, zero                        # set sign positive
1223         b       result_fs_s
1224
1225 /*
1226  * Double precision absolute value.
1227  */
1228 abs_d:
1229         jal     get_fs_d
1230         move    t0, zero                        # set sign positive
1231         b       result_fs_d
1232
1233 /*
1234  * Single precision move.
1235  */
1236 mov_s:
1237         jal     get_fs_s
1238         b       result_fs_s
1239
1240 /*
1241  * Double precision move.
1242  */
1243 mov_d:
1244         jal     get_fs_d
1245         b       result_fs_d
1246
1247 /*
1248  * Single precision negate.
1249  */
1250 neg_s:
1251         jal     get_fs_s
1252         xor     t0, t0, 1                       # reverse sign
1253         b       result_fs_s
1254
1255 /*
1256  * Double precision negate.
1257  */
1258 neg_d:
1259         jal     get_fs_d
1260         xor     t0, t0, 1                       # reverse sign
1261         b       result_fs_d
1262
1263 /*
1264  * Convert double to single.
1265  */
1266 cvt_s_d:
1267         jal     get_fs_d
1268         bne     t1, DEXP_INF, 1f                # is FS an infinity?
1269         li      t1, SEXP_INF                    # convert to single
1270         sll     t2, t2, 3                       # convert D fraction to S
1271         srl     t8, t3, 32 - 3
1272         or      t2, t2, t8
1273         b       result_fs_s
1274 1:
1275         bne     t1, zero, 2f                    # is FS zero?
1276         bne     t2, zero, 1f
1277         beq     t3, zero, result_fs_s           # result=0
1278 1:
1279         jal     renorm_fs_d
1280         subu    t1, t1, 3                       # correct exp for shift below
1281         b       3f
1282 2:
1283         subu    t1, t1, DEXP_BIAS               # unbias exponent
1284         or      t2, t2, DIMPL_ONE               # add implied one bit
1285 3:
1286         sll     t2, t2, 3                       # convert D fraction to S
1287         srl     t8, t3, 32 - 3
1288         or      t2, t2, t8
1289         sll     t8, t3, 3
1290         b       norm_noshift_s
1291
1292 /*
1293  * Convert integer to single.
1294  */
1295 cvt_s_w:
1296         jal     get_fs_int
1297         bne     t2, zero, 1f                    # check for zero
1298         move    t1, zero
1299         b       result_fs_s
1300 /*
1301  * Find out how many leading zero bits are in t2 and put in t9.
1302  */
1303 1:
1304         move    v0, t2
1305         move    t9, zero
1306         srl     v1, v0, 16
1307         bne     v1, zero, 1f
1308         addu    t9, 16
1309         sll     v0, 16
1310 1:
1311         srl     v1, v0, 24
1312         bne     v1, zero, 1f
1313         addu    t9, 8
1314         sll     v0, 8
1315 1:
1316         srl     v1, v0, 28
1317         bne     v1, zero, 1f
1318         addu    t9, 4
1319         sll     v0, 4
1320 1:
1321         srl     v1, v0, 30
1322         bne     v1, zero, 1f
1323         addu    t9, 2
1324         sll     v0, 2
1325 1:
1326         srl     v1, v0, 31
1327         bne     v1, zero, 1f
1328         addu    t9, 1
1329 /*
1330  * Now shift t2 the correct number of bits.
1331  */
1332 1:
1333         subu    t9, t9, SLEAD_ZEROS             # dont count leading zeros
1334         li      t1, 23                          # init exponent
1335         subu    t1, t1, t9                      # compute exponent
1336         beq     t9, zero, 1f
1337         li      v0, 32
1338         blt     t9, zero, 2f                    # if shift < 0, shift right
1339         subu    v0, v0, t9
1340         sll     t2, t2, t9                      # shift left
1341 1:
1342         add     t1, t1, SEXP_BIAS               # bias exponent
1343         and     t2, t2, ~SIMPL_ONE              # clear implied one bit
1344         b       result_fs_s
1345 2:
1346         negu    t9                              # shift right by t9
1347         subu    v0, v0, t9
1348         sll     t8, t2, v0                      # save bits shifted out
1349         srl     t2, t2, t9
1350         b       norm_noshift_s
1351
1352 /*
1353  * Convert single to double.
1354  */
1355 cvt_d_s:
1356         jal     get_fs_s
1357         move    t3, zero
1358         bne     t1, SEXP_INF, 1f                # is FS an infinity?
1359         li      t1, DEXP_INF                    # convert to double
1360         b       result_fs_d
1361 1:
1362         bne     t1, zero, 2f                    # is FS denormalized or zero?
1363         beq     t2, zero, result_fs_d           # is FS zero?
1364         jal     renorm_fs_s
1365         move    t8, zero
1366         b       norm_d
1367 2:
1368         addu    t1, t1, DEXP_BIAS - SEXP_BIAS   # bias exponent correctly
1369         sll     t3, t2, 32 - 3                  # convert S fraction to D
1370         srl     t2, t2, 3
1371         b       result_fs_d
1372
1373 /*
1374  * Convert integer to double.
1375  */
1376 cvt_d_w:
1377         jal     get_fs_int
1378         bne     t2, zero, 1f                    # check for zero
1379         move    t1, zero                        # result=0
1380         move    t3, zero
1381         b       result_fs_d
1382 /*
1383  * Find out how many leading zero bits are in t2 and put in t9.
1384  */
1385 1:
1386         move    v0, t2
1387         move    t9, zero
1388         srl     v1, v0, 16
1389         bne     v1, zero, 1f
1390         addu    t9, 16
1391         sll     v0, 16
1392 1:
1393         srl     v1, v0, 24
1394         bne     v1, zero, 1f
1395         addu    t9, 8
1396         sll     v0, 8
1397 1:
1398         srl     v1, v0, 28
1399         bne     v1, zero, 1f
1400         addu    t9, 4
1401         sll     v0, 4
1402 1:
1403         srl     v1, v0, 30
1404         bne     v1, zero, 1f
1405         addu    t9, 2
1406         sll     v0, 2
1407 1:
1408         srl     v1, v0, 31
1409         bne     v1, zero, 1f
1410         addu    t9, 1
1411 /*
1412  * Now shift t2 the correct number of bits.
1413  */
1414 1:
1415         subu    t9, t9, DLEAD_ZEROS             # dont count leading zeros
1416         li      t1, DEXP_BIAS + 20              # init exponent
1417         subu    t1, t1, t9                      # compute exponent
1418         beq     t9, zero, 1f
1419         li      v0, 32
1420         blt     t9, zero, 2f                    # if shift < 0, shift right
1421         subu    v0, v0, t9
1422         sll     t2, t2, t9                      # shift left
1423 1:
1424         and     t2, t2, ~DIMPL_ONE              # clear implied one bit
1425         move    t3, zero
1426         b       result_fs_d
1427 2:
1428         negu    t9                              # shift right by t9
1429         subu    v0, v0, t9
1430         sll     t3, t2, v0
1431         srl     t2, t2, t9
1432         and     t2, t2, ~DIMPL_ONE              # clear implied one bit
1433         b       result_fs_d
1434
1435 /*
1436  * Convert single to integer.
1437  */
1438 cvt_w_s:
1439         jal     get_fs_s
1440         bne     t1, SEXP_INF, 1f                # is FS an infinity?
1441         bne     t2, zero, invalid_w             # invalid conversion
1442 1:
1443         bne     t1, zero, 1f                    # is FS zero?
1444         beq     t2, zero, result_fs_w           # result is zero
1445         move    t2, zero                        # result is an inexact zero
1446         b       inexact_w
1447 1:
1448         subu    t1, t1, SEXP_BIAS               # unbias exponent
1449         or      t2, t2, SIMPL_ONE               # add implied one bit
1450         sll     t3, t2, 32 - 3                  # convert S fraction to D
1451         srl     t2, t2, 3
1452         b       cvt_w
1453
1454 /*
1455  * Convert double to integer.
1456  */
1457 cvt_w_d:
1458         jal     get_fs_d
1459         bne     t1, DEXP_INF, 1f                # is FS an infinity?
1460         bne     t2, zero, invalid_w             # invalid conversion
1461         bne     t3, zero, invalid_w             # invalid conversion
1462 1:
1463         bne     t1, zero, 2f                    # is FS zero?
1464         bne     t2, zero, 1f
1465         beq     t3, zero, result_fs_w           # result is zero
1466 1:
1467         move    t2, zero                        # result is an inexact zero
1468         b       inexact_w
1469 2:
1470         subu    t1, t1, DEXP_BIAS               # unbias exponent
1471         or      t2, t2, DIMPL_ONE               # add implied one bit
1472 cvt_w:
1473         blt     t1, WEXP_MIN, underflow_w       # is exponent too small?
1474         li      v0, WEXP_MAX+1
1475         bgt     t1, v0, overflow_w              # is exponent too large?
1476         bne     t1, v0, 1f                      # special check for INT_MIN
1477         beq     t0, zero, overflow_w            # if positive, overflow
1478         bne     t2, DIMPL_ONE, overflow_w
1479         bne     t3, zero, overflow_w
1480         li      t2, INT_MIN                     # result is INT_MIN
1481         b       result_fs_w
1482 1:
1483         subu    v0, t1, 20                      # compute amount to shift
1484         beq     v0, zero, 2f                    # is shift needed?
1485         li      v1, 32
1486         blt     v0, zero, 1f                    # if shift < 0, shift right
1487         subu    v1, v1, v0                      # shift left
1488         sll     t2, t2, v0
1489         srl     t9, t3, v1                      # save bits shifted out of t3
1490         or      t2, t2, t9                      # and put into t2
1491         sll     t3, t3, v0                      # shift FSs fraction
1492         b       2f
1493 1:
1494         negu    v0                              # shift right by v0
1495         subu    v1, v1, v0
1496         sll     t8, t3, v1                      # save bits shifted out
1497         sltu    t8, zero, t8                    # dont lose any ones
1498         srl     t3, t3, v0                      # shift FSs fraction
1499         or      t3, t3, t8
1500         sll     t9, t2, v1                      # save bits shifted out of t2
1501         or      t3, t3, t9                      # and put into t3
1502         srl     t2, t2, v0
1503 /*
1504  * round result (t0 is sign, t2 is integer part, t3 is fractional part).
1505  */
1506 2:
1507         and     v0, a1, MIPS_FPU_ROUNDING_BITS  # get rounding mode
1508         beq     v0, MIPS_FPU_ROUND_RN, 3f       # round to nearest
1509         beq     v0, MIPS_FPU_ROUND_RZ, 5f       # round to zero (truncate)
1510         beq     v0, MIPS_FPU_ROUND_RP, 1f       # round to +infinity
1511         beq     t0, zero, 5f                    # if sign is positive, truncate
1512         b       2f
1513 1:
1514         bne     t0, zero, 5f                    # if sign is negative, truncate
1515 2:
1516         beq     t3, zero, 5f                    # if no fraction bits, continue
1517         addu    t2, t2, 1                       # add rounding bit
1518         blt     t2, zero, overflow_w            # overflow?
1519         b       5f
1520 3:
1521         li      v0, GUARDBIT                    # load guard bit for rounding
1522         addu    v0, v0, t3                      # add remainder
1523         sltu    v1, v0, t3                      # compute carry out
1524         beq     v1, zero, 4f                    # if no carry, continue
1525         addu    t2, t2, 1                       # add carry to result
1526         blt     t2, zero, overflow_w            # overflow?
1527 4:
1528         bne     v0, zero, 5f                    # if rounded remainder is zero
1529         and     t2, t2, ~1                      #  clear LSB (round to nearest)
1530 5:
1531         beq     t0, zero, 1f                    # result positive?
1532         negu    t2                              # convert to negative integer
1533 1:
1534         beq     t3, zero, result_fs_w           # is result exact?
1535 /*
1536  * Handle inexact exception.
1537  */
1538 inexact_w:
1539         or      a1, a1, MIPS_FPU_EXCEPTION_INEXACT | MIPS_FPU_STICKY_INEXACT
1540         and     v0, a1, MIPS_FPU_ENABLE_INEXACT
1541         bne     v0, zero, fpe_trap
1542         ctc1    a1, MIPS_FPU_CSR                # save exceptions
1543         b       result_fs_w
1544
1545 /*
1546  * Conversions to integer which overflow will trap (if enabled),
1547  * or generate an inexact trap (if enabled),
1548  * or generate an invalid exception.
1549  */
1550 overflow_w:
1551         or      a1, a1, MIPS_FPU_EXCEPTION_OVERFLOW | MIPS_FPU_STICKY_OVERFLOW
1552         and     v0, a1, MIPS_FPU_ENABLE_OVERFLOW
1553         bne     v0, zero, fpe_trap
1554         and     v0, a1, MIPS_FPU_ENABLE_INEXACT
1555         bne     v0, zero, inexact_w             # inexact traps enabled?
1556         b       invalid_w
1557
1558 /*
1559  * Conversions to integer which underflow will trap (if enabled),
1560  * or generate an inexact trap (if enabled),
1561  * or generate an invalid exception.
1562  */
1563 underflow_w:
1564         or      a1, a1, MIPS_FPU_EXCEPTION_UNDERFLOW | MIPS_FPU_STICKY_UNDERFLOW
1565         and     v0, a1, MIPS_FPU_ENABLE_UNDERFLOW
1566         bne     v0, zero, fpe_trap
1567         and     v0, a1, MIPS_FPU_ENABLE_INEXACT
1568         bne     v0, zero, inexact_w             # inexact traps enabled?
1569         b       invalid_w
1570
1571 /*
1572  * Compare single.
1573  */
1574 cmp_s:
1575         jal     get_cmp_s
1576         bne     t1, SEXP_INF, 1f                # is FS an infinity?
1577         bne     t2, zero, unordered             # FS is a NAN
1578 1:
1579         bne     ta1, SEXP_INF, 2f               # is FT an infinity?
1580         bne     ta2, zero, unordered            # FT is a NAN
1581 2:
1582         sll     t1, t1, 23                      # reassemble exp & frac
1583         or      t1, t1, t2
1584         sll     ta1, ta1, 23                    # reassemble exp & frac
1585         or      ta1, ta1, ta2
1586         beq     t0, zero, 1f                    # is FS positive?
1587         negu    t1
1588 1:
1589         beq     ta0, zero, 1f                   # is FT positive?
1590         negu    ta1
1591 1:
1592         li      v0, COND_LESS
1593         blt     t1, ta1, test_cond              # is FS < FT?
1594         li      v0, COND_EQUAL
1595         beq     t1, ta1, test_cond              # is FS == FT?
1596         move    v0, zero                        # FS > FT
1597         b       test_cond
1598
1599 /*
1600  * Compare double.
1601  */
1602 cmp_d:
1603         jal     get_cmp_d
1604         bne     t1, DEXP_INF, 1f                # is FS an infinity?
1605         bne     t2, zero, unordered
1606         bne     t3, zero, unordered             # FS is a NAN
1607 1:
1608         bne     ta1, DEXP_INF, 2f               # is FT an infinity?
1609         bne     ta2, zero, unordered
1610         bne     ta3, zero, unordered            # FT is a NAN
1611 2:
1612         sll     t1, t1, 20                      # reassemble exp & frac
1613         or      t1, t1, t2
1614         sll     ta1, ta1, 20                    # reassemble exp & frac
1615         or      ta1, ta1, ta2
1616         beq     t0, zero, 1f                    # is FS positive?
1617         not     t3                              # negate t1,t3
1618         not     t1
1619         addu    t3, t3, 1
1620         seq     v0, t3, zero                    # compute carry
1621         addu    t1, t1, v0
1622 1:
1623         beq     ta0, zero, 1f                   # is FT positive?
1624         not     ta3                             # negate ta1,ta3
1625         not     ta1
1626         addu    ta3, ta3, 1
1627         seq     v0, ta3, zero                   # compute carry
1628         addu    ta1, ta1, v0
1629 1:
1630         li      v0, COND_LESS
1631         blt     t1, ta1, test_cond              # is FS(MSW) < FT(MSW)?
1632         move    v0, zero
1633         bne     t1, ta1, test_cond              # is FS(MSW) > FT(MSW)?
1634         li      v0, COND_LESS
1635         bltu    t3, ta3, test_cond              # is FS(LSW) < FT(LSW)?
1636         li      v0, COND_EQUAL
1637         beq     t3, ta3, test_cond              # is FS(LSW) == FT(LSW)?
1638         move    v0, zero                        # FS > FT
1639 test_cond:
1640         and     v0, v0, a0                      # condition match instruction?
1641 set_cond:
1642         bne     v0, zero, 1f
1643         and     a1, a1, ~MIPS_FPU_COND_BIT      # clear condition bit
1644         b       2f
1645 1:
1646         or      a1, a1, MIPS_FPU_COND_BIT       # set condition bit
1647 2:
1648         ctc1    a1, MIPS_FPU_CSR                # save condition bit
1649         b       done
1650
1651 unordered:
1652         and     v0, a0, COND_UNORDERED          # this cmp match unordered?
1653         bne     v0, zero, 1f
1654         and     a1, a1, ~MIPS_FPU_COND_BIT      # clear condition bit
1655         b       2f
1656 1:
1657         or      a1, a1, MIPS_FPU_COND_BIT       # set condition bit
1658 2:
1659         and     v0, a0, COND_SIGNAL
1660         beq     v0, zero, 1f                    # is this a signaling cmp?
1661         or      a1, a1, MIPS_FPU_EXCEPTION_INVALID | MIPS_FPU_STICKY_INVALID
1662         and     v0, a1, MIPS_FPU_ENABLE_INVALID
1663         bne     v0, zero, fpe_trap
1664 1:
1665         ctc1    a1, MIPS_FPU_CSR                # save condition bit
1666         b       done
1667
1668 /*
1669  * Determine the amount to shift the fraction in order to restore the
1670  * normalized position. After that, round and handle exceptions.
1671  */
1672 norm_s:
1673         move    v0, t2
1674         move    t9, zero                        # t9 = num of leading zeros
1675         bne     t2, zero, 1f
1676         move    v0, t8
1677         addu    t9, 32
1678 1:
1679         srl     v1, v0, 16
1680         bne     v1, zero, 1f
1681         addu    t9, 16
1682         sll     v0, 16
1683 1:
1684         srl     v1, v0, 24
1685         bne     v1, zero, 1f
1686         addu    t9, 8
1687         sll     v0, 8
1688 1:
1689         srl     v1, v0, 28
1690         bne     v1, zero, 1f
1691         addu    t9, 4
1692         sll     v0, 4
1693 1:
1694         srl     v1, v0, 30
1695         bne     v1, zero, 1f
1696         addu    t9, 2
1697         sll     v0, 2
1698 1:
1699         srl     v1, v0, 31
1700         bne     v1, zero, 1f
1701         addu    t9, 1
1702 /*
1703  * Now shift t2,t8 the correct number of bits.
1704  */
1705 1:
1706         subu    t9, t9, SLEAD_ZEROS             # dont count leading zeros
1707         subu    t1, t1, t9                      # adjust the exponent
1708         beq     t9, zero, norm_noshift_s
1709         li      v1, 32
1710         blt     t9, zero, 1f                    # if shift < 0, shift right
1711         subu    v1, v1, t9
1712         sll     t2, t2, t9                      # shift t2,t8 left
1713         srl     v0, t8, v1                      # save bits shifted out
1714         or      t2, t2, v0
1715         sll     t8, t8, t9
1716         b       norm_noshift_s
1717 1:
1718         negu    t9                              # shift t2,t8 right by t9
1719         subu    v1, v1, t9
1720         sll     v0, t8, v1                      # save bits shifted out
1721         sltu    v0, zero, v0                    # be sure to save any one bits
1722         srl     t8, t8, t9
1723         or      t8, t8, v0
1724         sll     v0, t2, v1                      # save bits shifted out
1725         or      t8, t8, v0
1726         srl     t2, t2, t9
1727 norm_noshift_s:
1728         move    ta1, t1                         # save unrounded exponent
1729         move    ta2, t2                         # save unrounded fraction
1730         and     v0, a1, MIPS_FPU_ROUNDING_BITS  # get rounding mode
1731         beq     v0, MIPS_FPU_ROUND_RN, 3f       # round to nearest
1732         beq     v0, MIPS_FPU_ROUND_RZ, 5f       # round to zero (truncate)
1733         beq     v0, MIPS_FPU_ROUND_RP, 1f       # round to +infinity
1734         beq     t0, zero, 5f                    # if sign is positive, truncate
1735         b       2f
1736 1:
1737         bne     t0, zero, 5f                    # if sign is negative, truncate
1738 2:
1739         beq     t8, zero, 5f                    # if exact, continue
1740         addu    t2, t2, 1                       # add rounding bit
1741         bne     t2, SIMPL_ONE<<1, 5f            # need to adjust exponent?
1742         addu    t1, t1, 1                       # adjust exponent
1743         srl     t2, t2, 1                       # renormalize fraction
1744         b       5f
1745 3:
1746         li      v0, GUARDBIT                    # load guard bit for rounding
1747         addu    v0, v0, t8                      # add remainder
1748         sltu    v1, v0, t8                      # compute carry out
1749         beq     v1, zero, 4f                    # if no carry, continue
1750         addu    t2, t2, 1                       # add carry to result
1751         bne     t2, SIMPL_ONE<<1, 4f            # need to adjust exponent?
1752         addu    t1, t1, 1                       # adjust exponent
1753         srl     t2, t2, 1                       # renormalize fraction
1754 4:
1755         bne     v0, zero, 5f                    # if rounded remainder is zero
1756         and     t2, t2, ~1                      #  clear LSB (round to nearest)
1757 5:
1758         bgt     t1, SEXP_MAX, overflow_s        # overflow?
1759         blt     t1, SEXP_MIN, underflow_s       # underflow?
1760         bne     t8, zero, inexact_s             # is result inexact?
1761         addu    t1, t1, SEXP_BIAS               # bias exponent
1762         and     t2, t2, ~SIMPL_ONE              # clear implied one bit
1763         b       result_fs_s
1764
1765 /*
1766  * Handle inexact exception.
1767  */
1768 inexact_s:
1769         addu    t1, t1, SEXP_BIAS               # bias exponent
1770         and     t2, t2, ~SIMPL_ONE              # clear implied one bit
1771 inexact_nobias_s:
1772         jal     set_fd_s                        # save result
1773         or      a1, a1, MIPS_FPU_EXCEPTION_INEXACT | MIPS_FPU_STICKY_INEXACT
1774         and     v0, a1, MIPS_FPU_ENABLE_INEXACT
1775         bne     v0, zero, fpe_trap
1776         ctc1    a1, MIPS_FPU_CSR                # save exceptions
1777         b       done
1778
1779 /*
1780  * Overflow will trap (if enabled),
1781  * or generate an inexact trap (if enabled),
1782  * or generate an infinity.
1783  */
1784 overflow_s:
1785         or      a1, a1, MIPS_FPU_EXCEPTION_OVERFLOW | MIPS_FPU_STICKY_OVERFLOW
1786         and     v0, a1, MIPS_FPU_ENABLE_OVERFLOW
1787         beq     v0, zero, 1f
1788         subu    t1, t1, 192                     # bias exponent
1789         and     t2, t2, ~SIMPL_ONE              # clear implied one bit
1790         jal     set_fd_s                        # save result
1791         b       fpe_trap
1792 1:
1793         and     v0, a1, MIPS_FPU_ROUNDING_BITS  # get rounding mode
1794         beq     v0, MIPS_FPU_ROUND_RN, 3f       # round to nearest
1795         beq     v0, MIPS_FPU_ROUND_RZ, 1f       # round to zero (truncate)
1796         beq     v0, MIPS_FPU_ROUND_RP, 2f       # round to +infinity
1797         bne     t0, zero, 3f
1798 1:
1799         li      t1, SEXP_MAX                    # result is max finite
1800         li      t2, 0x007fffff
1801         b       inexact_s
1802 2:
1803         bne     t0, zero, 1b
1804 3:
1805         li      t1, SEXP_MAX + 1                # result is infinity
1806         move    t2, zero
1807         b       inexact_s
1808
1809 /*
1810  * In this implementation, "tininess" is detected "after rounding" and
1811  * "loss of accuracy" is detected as "an inexact result".
1812  */
1813 underflow_s:
1814         and     v0, a1, MIPS_FPU_ENABLE_UNDERFLOW
1815         beq     v0, zero, 1f
1816 /*
1817  * Underflow is enabled so compute the result and trap.
1818  */
1819         addu    t1, t1, 192                     # bias exponent
1820         and     t2, t2, ~SIMPL_ONE              # clear implied one bit
1821         jal     set_fd_s                        # save result
1822         or      a1, a1, MIPS_FPU_EXCEPTION_UNDERFLOW | MIPS_FPU_STICKY_UNDERFLOW
1823         b       fpe_trap
1824 /*
1825  * Underflow is not enabled so compute the result,
1826  * signal inexact result (if it is) and trap (if enabled).
1827  */
1828 1:
1829         move    t1, ta1                         # get unrounded exponent
1830         move    t2, ta2                         # get unrounded fraction
1831         li      t9, SEXP_MIN                    # compute shift amount
1832         subu    t9, t9, t1                      # shift t2,t8 right by t9
1833         blt     t9, SFRAC_BITS+2, 3f            # shift all the bits out?
1834         move    t1, zero                        # result is inexact zero
1835         move    t2, zero
1836         or      a1, a1, MIPS_FPU_EXCEPTION_UNDERFLOW | MIPS_FPU_STICKY_UNDERFLOW
1837 /*
1838  * Now round the zero result.
1839  * Only need to worry about rounding to +- infinity when the sign matches.
1840  */
1841         and     v0, a1, MIPS_FPU_ROUNDING_BITS  # get rounding mode
1842         beq     v0, MIPS_FPU_ROUND_RN, inexact_nobias_s # round to nearest
1843         beq     v0, MIPS_FPU_ROUND_RZ, inexact_nobias_s # round to zero
1844         beq     v0, MIPS_FPU_ROUND_RP, 1f               # round to +infinity
1845         beq     t0, zero, inexact_nobias_s      # if sign is positive, truncate
1846         b       2f
1847 1:
1848         bne     t0, zero, inexact_nobias_s      # if sign is negative, truncate
1849 2:
1850         addu    t2, t2, 1                       # add rounding bit
1851         b       inexact_nobias_s
1852 3:
1853         li      v1, 32
1854         subu    v1, v1, t9
1855         sltu    v0, zero, t8                    # be sure to save any one bits
1856         sll     t8, t2, v1                      # save bits shifted out
1857         or      t8, t8, v0                      # include sticky bits
1858         srl     t2, t2, t9
1859 /*
1860  * Now round the denormalized result.
1861  */
1862         and     v0, a1, MIPS_FPU_ROUNDING_BITS  # get rounding mode
1863         beq     v0, MIPS_FPU_ROUND_RN, 3f       # round to nearest
1864         beq     v0, MIPS_FPU_ROUND_RZ, 5f       # round to zero (truncate)
1865         beq     v0, MIPS_FPU_ROUND_RP, 1f       # round to +infinity
1866         beq     t0, zero, 5f                    # if sign is positive, truncate
1867         b       2f
1868 1:
1869         bne     t0, zero, 5f                    # if sign is negative, truncate
1870 2:
1871         beq     t8, zero, 5f                    # if exact, continue
1872         addu    t2, t2, 1                       # add rounding bit
1873         b       5f
1874 3:
1875         li      v0, GUARDBIT                    # load guard bit for rounding
1876         addu    v0, v0, t8                      # add remainder
1877         sltu    v1, v0, t8                      # compute carry out
1878         beq     v1, zero, 4f                    # if no carry, continue
1879         addu    t2, t2, 1                       # add carry to result
1880 4:
1881         bne     v0, zero, 5f                    # if rounded remainder is zero
1882         and     t2, t2, ~1                      #  clear LSB (round to nearest)
1883 5:
1884         move    t1, zero                        # denorm or zero exponent
1885         jal     set_fd_s                        # save result
1886         beq     t8, zero, done                  # check for exact result
1887         or      a1, a1, MIPS_FPU_EXCEPTION_UNDERFLOW | MIPS_FPU_STICKY_UNDERFLOW
1888         or      a1, a1, MIPS_FPU_EXCEPTION_INEXACT | MIPS_FPU_STICKY_INEXACT
1889         and     v0, a1, MIPS_FPU_ENABLE_INEXACT
1890         bne     v0, zero, fpe_trap
1891         ctc1    a1, MIPS_FPU_CSR                # save exceptions
1892         b       done
1893
1894 /*
1895  * Determine the amount to shift the fraction in order to restore the
1896  * normalized position. After that, round and handle exceptions.
1897  */
1898 norm_d:
1899         move    v0, t2
1900         move    t9, zero                        # t9 = num of leading zeros
1901         bne     t2, zero, 1f
1902         move    v0, t3
1903         addu    t9, 32
1904         bne     t3, zero, 1f
1905         move    v0, t8
1906         addu    t9, 32
1907 1:
1908         srl     v1, v0, 16
1909         bne     v1, zero, 1f
1910         addu    t9, 16
1911         sll     v0, 16
1912 1:
1913         srl     v1, v0, 24
1914         bne     v1, zero, 1f
1915         addu    t9, 8
1916         sll     v0, 8
1917 1:
1918         srl     v1, v0, 28
1919         bne     v1, zero, 1f
1920         addu    t9, 4
1921         sll     v0, 4
1922 1:
1923         srl     v1, v0, 30
1924         bne     v1, zero, 1f
1925         addu    t9, 2
1926         sll     v0, 2
1927 1:
1928         srl     v1, v0, 31
1929         bne     v1, zero, 1f
1930         addu    t9, 1
1931 /*
1932  * Now shift t2,t3,t8 the correct number of bits.
1933  */
1934 1:
1935         subu    t9, t9, DLEAD_ZEROS             # dont count leading zeros
1936         subu    t1, t1, t9                      # adjust the exponent
1937         beq     t9, zero, norm_noshift_d
1938         li      v1, 32
1939         blt     t9, zero, 2f                    # if shift < 0, shift right
1940         blt     t9, v1, 1f                      # shift by < 32?
1941         subu    t9, t9, v1                      # shift by >= 32
1942         subu    v1, v1, t9
1943         sll     t2, t3, t9                      # shift left by t9
1944         srl     v0, t8, v1                      # save bits shifted out
1945         or      t2, t2, v0
1946         sll     t3, t8, t9
1947         move    t8, zero
1948         b       norm_noshift_d
1949 1:
1950         subu    v1, v1, t9
1951         sll     t2, t2, t9                      # shift left by t9
1952         srl     v0, t3, v1                      # save bits shifted out
1953         or      t2, t2, v0
1954         sll     t3, t3, t9
1955         srl     v0, t8, v1                      # save bits shifted out
1956         or      t3, t3, v0
1957         sll     t8, t8, t9
1958         b       norm_noshift_d
1959 2:
1960         negu    t9                              # shift right by t9
1961         subu    v1, v1, t9                      #  (known to be < 32 bits)
1962         sll     v0, t8, v1                      # save bits shifted out
1963         sltu    v0, zero, v0                    # be sure to save any one bits
1964         srl     t8, t8, t9
1965         or      t8, t8, v0
1966         sll     v0, t3, v1                      # save bits shifted out
1967         or      t8, t8, v0
1968         srl     t3, t3, t9
1969         sll     v0, t2, v1                      # save bits shifted out
1970         or      t3, t3, v0
1971         srl     t2, t2, t9
1972 norm_noshift_d:
1973         move    ta1, t1                         # save unrounded exponent
1974         move    ta2, t2                         # save unrounded fraction (MS)
1975         move    ta3, t3                         # save unrounded fraction (LS)
1976         and     v0, a1, MIPS_FPU_ROUNDING_BITS  # get rounding mode
1977         beq     v0, MIPS_FPU_ROUND_RN, 3f       # round to nearest
1978         beq     v0, MIPS_FPU_ROUND_RZ, 5f       # round to zero (truncate)
1979         beq     v0, MIPS_FPU_ROUND_RP, 1f       # round to +infinity
1980         beq     t0, zero, 5f                    # if sign is positive, truncate
1981         b       2f
1982 1:
1983         bne     t0, zero, 5f                    # if sign is negative, truncate
1984 2:
1985         beq     t8, zero, 5f                    # if exact, continue
1986         addu    t3, t3, 1                       # add rounding bit
1987         bne     t3, zero, 5f                    # branch if no carry
1988         addu    t2, t2, 1                       # add carry
1989         bne     t2, DIMPL_ONE<<1, 5f            # need to adjust exponent?
1990         addu    t1, t1, 1                       # adjust exponent
1991         srl     t2, t2, 1                       # renormalize fraction
1992         b       5f
1993 3:
1994         li      v0, GUARDBIT                    # load guard bit for rounding
1995         addu    v0, v0, t8                      # add remainder
1996         sltu    v1, v0, t8                      # compute carry out
1997         beq     v1, zero, 4f                    # branch if no carry
1998         addu    t3, t3, 1                       # add carry
1999         bne     t3, zero, 4f                    # branch if no carry
2000         addu    t2, t2, 1                       # add carry to result
2001         bne     t2, DIMPL_ONE<<1, 4f            # need to adjust exponent?
2002         addu    t1, t1, 1                       # adjust exponent
2003         srl     t2, t2, 1                       # renormalize fraction
2004 4:
2005         bne     v0, zero, 5f                    # if rounded remainder is zero
2006         and     t3, t3, ~1                      #  clear LSB (round to nearest)
2007 5:
2008         bgt     t1, DEXP_MAX, overflow_d        # overflow?
2009         blt     t1, DEXP_MIN, underflow_d       # underflow?
2010         bne     t8, zero, inexact_d             # is result inexact?
2011         addu    t1, t1, DEXP_BIAS               # bias exponent
2012         and     t2, t2, ~DIMPL_ONE              # clear implied one bit
2013         b       result_fs_d
2014
2015 /*
2016  * Handle inexact exception.
2017  */
2018 inexact_d:
2019         addu    t1, t1, DEXP_BIAS               # bias exponent
2020         and     t2, t2, ~DIMPL_ONE              # clear implied one bit
2021 inexact_nobias_d:
2022         jal     set_fd_d                        # save result
2023         or      a1, a1, MIPS_FPU_EXCEPTION_INEXACT | MIPS_FPU_STICKY_INEXACT
2024         and     v0, a1, MIPS_FPU_ENABLE_INEXACT
2025         bne     v0, zero, fpe_trap
2026         ctc1    a1, MIPS_FPU_CSR                # save exceptions
2027         b       done
2028
2029 /*
2030  * Overflow will trap (if enabled),
2031  * or generate an inexact trap (if enabled),
2032  * or generate an infinity.
2033  */
2034 overflow_d:
2035         or      a1, a1, MIPS_FPU_EXCEPTION_OVERFLOW | MIPS_FPU_STICKY_OVERFLOW
2036         and     v0, a1, MIPS_FPU_ENABLE_OVERFLOW
2037         beq     v0, zero, 1f
2038         subu    t1, t1, 1536                    # bias exponent
2039         and     t2, t2, ~DIMPL_ONE              # clear implied one bit
2040         jal     set_fd_d                        # save result
2041         b       fpe_trap
2042 1:
2043         and     v0, a1, MIPS_FPU_ROUNDING_BITS  # get rounding mode
2044         beq     v0, MIPS_FPU_ROUND_RN, 3f       # round to nearest
2045         beq     v0, MIPS_FPU_ROUND_RZ, 1f       # round to zero (truncate)
2046         beq     v0, MIPS_FPU_ROUND_RP, 2f       # round to +infinity
2047         bne     t0, zero, 3f
2048 1:
2049         li      t1, DEXP_MAX                    # result is max finite
2050         li      t2, 0x000fffff
2051         li      t3, 0xffffffff
2052         b       inexact_d
2053 2:
2054         bne     t0, zero, 1b
2055 3:
2056         li      t1, DEXP_MAX + 1                # result is infinity
2057         move    t2, zero
2058         move    t3, zero
2059         b       inexact_d
2060
2061 /*
2062  * In this implementation, "tininess" is detected "after rounding" and
2063  * "loss of accuracy" is detected as "an inexact result".
2064  */
2065 underflow_d:
2066         and     v0, a1, MIPS_FPU_ENABLE_UNDERFLOW
2067         beq     v0, zero, 1f
2068 /*
2069  * Underflow is enabled so compute the result and trap.
2070  */
2071         addu    t1, t1, 1536                    # bias exponent
2072         and     t2, t2, ~DIMPL_ONE              # clear implied one bit
2073         jal     set_fd_d                        # save result
2074         or      a1, a1, MIPS_FPU_EXCEPTION_UNDERFLOW | MIPS_FPU_STICKY_UNDERFLOW
2075         b       fpe_trap
2076 /*
2077  * Underflow is not enabled so compute the result,
2078  * signal inexact result (if it is) and trap (if enabled).
2079  */
2080 1:
2081         move    t1, ta1                         # get unrounded exponent
2082         move    t2, ta2                         # get unrounded fraction (MS)
2083         move    t3, ta3                         # get unrounded fraction (LS)
2084         li      t9, DEXP_MIN                    # compute shift amount
2085         subu    t9, t9, t1                      # shift t2,t8 right by t9
2086         blt     t9, DFRAC_BITS+2, 3f            # shift all the bits out?
2087         move    t1, zero                        # result is inexact zero
2088         move    t2, zero
2089         move    t3, zero
2090         or      a1, a1, MIPS_FPU_EXCEPTION_UNDERFLOW | MIPS_FPU_STICKY_UNDERFLOW
2091 /*
2092  * Now round the zero result.
2093  * Only need to worry about rounding to +- infinity when the sign matches.
2094  */
2095         and     v0, a1, MIPS_FPU_ROUNDING_BITS  # get rounding mode
2096         beq     v0, MIPS_FPU_ROUND_RN, inexact_nobias_d  # round to nearest
2097         beq     v0, MIPS_FPU_ROUND_RZ, inexact_nobias_d  # round to zero
2098         beq     v0, MIPS_FPU_ROUND_RP, 1f               # round to +infinity
2099         beq     t0, zero, inexact_nobias_d      # if sign is positive, truncate
2100         b       2f
2101 1:
2102         bne     t0, zero, inexact_nobias_d      # if sign is negative, truncate
2103 2:
2104         addu    t3, t3, 1                       # add rounding bit
2105         b       inexact_nobias_d
2106 3:
2107         li      v1, 32
2108         blt     t9, v1, 1f                      # shift by < 32?
2109         subu    t9, t9, v1                      # shift right by >= 32
2110         subu    v1, v1, t9
2111         sltu    v0, zero, t8                    # be sure to save any one bits
2112         sll     t8, t2, v1                      # save bits shifted out
2113         or      t8, t8, v0                      # include sticky bits
2114         srl     t3, t2, t9
2115         move    t2, zero
2116         b       2f
2117 1:
2118         subu    v1, v1, t9                      # shift right by t9
2119         sltu    v0, zero, t8                    # be sure to save any one bits
2120         sll     t8, t3, v1                      # save bits shifted out
2121         or      t8, t8, v0                      # include sticky bits
2122         srl     t3, t3, t9
2123         sll     v0, t2, v1                      # save bits shifted out
2124         or      t3, t3, v0
2125         srl     t2, t2, t9
2126 /*
2127  * Now round the denormalized result.
2128  */
2129 2:
2130         and     v0, a1, MIPS_FPU_ROUNDING_BITS  # get rounding mode
2131         beq     v0, MIPS_FPU_ROUND_RN, 3f       # round to nearest
2132         beq     v0, MIPS_FPU_ROUND_RZ, 5f       # round to zero (truncate)
2133         beq     v0, MIPS_FPU_ROUND_RP, 1f       # round to +infinity
2134         beq     t0, zero, 5f                    # if sign is positive, truncate
2135         b       2f
2136 1:
2137         bne     t0, zero, 5f                    # if sign is negative, truncate
2138 2:
2139         beq     t8, zero, 5f                    # if exact, continue
2140         addu    t3, t3, 1                       # add rounding bit
2141         bne     t3, zero, 5f                    # if no carry, continue
2142         addu    t2, t2, 1                       # add carry
2143         b       5f
2144 3:
2145         li      v0, GUARDBIT                    # load guard bit for rounding
2146         addu    v0, v0, t8                      # add remainder
2147         sltu    v1, v0, t8                      # compute carry out
2148         beq     v1, zero, 4f                    # if no carry, continue
2149         addu    t3, t3, 1                       # add rounding bit
2150         bne     t3, zero, 4f                    # if no carry, continue
2151         addu    t2, t2, 1                       # add carry
2152 4:
2153         bne     v0, zero, 5f                    # if rounded remainder is zero
2154         and     t3, t3, ~1                      #  clear LSB (round to nearest)
2155 5:
2156         move    t1, zero                        # denorm or zero exponent
2157         jal     set_fd_d                        # save result
2158         beq     t8, zero, done                  # check for exact result
2159         or      a1, a1, MIPS_FPU_EXCEPTION_UNDERFLOW | MIPS_FPU_STICKY_UNDERFLOW
2160         or      a1, a1, MIPS_FPU_EXCEPTION_INEXACT | MIPS_FPU_STICKY_INEXACT
2161         and     v0, a1, MIPS_FPU_ENABLE_INEXACT
2162         bne     v0, zero, fpe_trap
2163         ctc1    a1, MIPS_FPU_CSR                # save exceptions
2164         b       done
2165
2166 /*
2167  * Signal an invalid operation if the trap is enabled; otherwise,
2168  * the result is a quiet NAN.
2169  */
2170 invalid_s:                                      # trap invalid operation
2171         or      a1, a1, MIPS_FPU_EXCEPTION_INVALID | MIPS_FPU_STICKY_INVALID
2172         and     v0, a1, MIPS_FPU_ENABLE_INVALID
2173         bne     v0, zero, fpe_trap
2174         ctc1    a1, MIPS_FPU_CSR                # save exceptions
2175         move    t0, zero                        # result is a quiet NAN
2176         li      t1, SEXP_INF
2177         li      t2, SQUIET_NAN
2178         jal     set_fd_s                        # save result (in t0,t1,t2)
2179         b       done
2180
2181 /*
2182  * Signal an invalid operation if the trap is enabled; otherwise,
2183  * the result is a quiet NAN.
2184  */
2185 invalid_d:                                      # trap invalid operation
2186         or      a1, a1, MIPS_FPU_EXCEPTION_INVALID | MIPS_FPU_STICKY_INVALID
2187         and     v0, a1, MIPS_FPU_ENABLE_INVALID
2188         bne     v0, zero, fpe_trap
2189         ctc1    a1, MIPS_FPU_CSR                # save exceptions
2190         move    t0, zero                        # result is a quiet NAN
2191         li      t1, DEXP_INF
2192         li      t2, DQUIET_NAN0
2193         li      t3, DQUIET_NAN1
2194         jal     set_fd_d                        # save result (in t0,t1,t2,t3)
2195         b       done
2196
2197 /*
2198  * Signal an invalid operation if the trap is enabled; otherwise,
2199  * the result is INT_MAX or INT_MIN.
2200  */
2201 invalid_w:                                      # trap invalid operation
2202         or      a1, a1, MIPS_FPU_EXCEPTION_INVALID | MIPS_FPU_STICKY_INVALID
2203         and     v0, a1, MIPS_FPU_ENABLE_INVALID
2204         bne     v0, zero, fpe_trap
2205         ctc1    a1, MIPS_FPU_CSR                # save exceptions
2206         bne     t0, zero, 1f
2207         li      t2, INT_MAX                     # result is INT_MAX
2208         b       result_fs_w
2209 1:
2210         li      t2, INT_MIN                     # result is INT_MIN
2211         b       result_fs_w
2212
2213 /*
2214  * Trap if the hardware should have handled this case.
2215  */
2216 fpe_trap:
2217         move    a2, a1                          # code = FP CSR
2218         ctc1    a1, MIPS_FPU_CSR                # save exceptions
2219         break   0
2220
2221 /*
2222  * Send an illegal instruction signal to the current process.
2223  */
2224 ill:
2225         ctc1    a1, MIPS_FPU_CSR                # save exceptions
2226         move    a2, a0                          # code = FP instruction
2227         break   0
2228
2229 result_ft_s:
2230         move    t0, ta0                         # result is FT
2231         move    t1, ta1
2232         move    t2, ta2
2233 result_fs_s:                                    # result is FS
2234         jal     set_fd_s                        # save result (in t0,t1,t2)
2235         b       done
2236
2237 result_fs_w:
2238         jal     set_fd_word                     # save result (in t2)
2239         b       done
2240
2241 result_ft_d:
2242         move    t0, ta0                         # result is FT
2243         move    t1, ta1
2244         move    t2, ta2
2245         move    t3, ta3
2246 result_fs_d:                                    # result is FS
2247         jal     set_fd_d                        # save result (in t0,t1,t2,t3)
2248
2249 done:
2250         lw      ra, CALLFRAME_RA(sp)
2251         addu    sp, sp, CALLFRAME_SIZ
2252         j       ra
2253 END(MipsEmulateFP)
2254
2255 /*----------------------------------------------------------------------------
2256  * get_fs_int --
2257  *
2258  *      Read (integer) the FS register (bits 15-11).
2259  *      This is an internal routine used by MipsEmulateFP only.
2260  *
2261  * Results:
2262  *      t0      contains the sign
2263  *      t2      contains the fraction
2264  *
2265  *----------------------------------------------------------------------------
2266  */
2267 LEAF(get_fs_int)
2268         srl     a3, a0, 12 - 2                  # get FS field (even regs only)
2269         and     a3, a3, 0xF << 2                # mask FS field
2270         lw      a3, get_fs_int_tbl(a3)          # switch on register number
2271         j       a3
2272
2273         .rdata
2274 get_fs_int_tbl:
2275         .word   get_fs_int_f0
2276         .word   get_fs_int_f2
2277         .word   get_fs_int_f4
2278         .word   get_fs_int_f6
2279         .word   get_fs_int_f8
2280         .word   get_fs_int_f10
2281         .word   get_fs_int_f12
2282         .word   get_fs_int_f14
2283         .word   get_fs_int_f16
2284         .word   get_fs_int_f18
2285         .word   get_fs_int_f20
2286         .word   get_fs_int_f22
2287         .word   get_fs_int_f24
2288         .word   get_fs_int_f26
2289         .word   get_fs_int_f28
2290         .word   get_fs_int_f30
2291         .text
2292
2293 get_fs_int_f0:
2294         mfc1    t2, $f0
2295         b       get_fs_int_done
2296 get_fs_int_f2:
2297         mfc1    t2, $f2
2298         b       get_fs_int_done
2299 get_fs_int_f4:
2300         mfc1    t2, $f4
2301         b       get_fs_int_done
2302 get_fs_int_f6:
2303         mfc1    t2, $f6
2304         b       get_fs_int_done
2305 get_fs_int_f8:
2306         mfc1    t2, $f8
2307         b       get_fs_int_done
2308 get_fs_int_f10:
2309         mfc1    t2, $f10
2310         b       get_fs_int_done
2311 get_fs_int_f12:
2312         mfc1    t2, $f12
2313         b       get_fs_int_done
2314 get_fs_int_f14:
2315         mfc1    t2, $f14
2316         b       get_fs_int_done
2317 get_fs_int_f16:
2318         mfc1    t2, $f16
2319         b       get_fs_int_done
2320 get_fs_int_f18:
2321         mfc1    t2, $f18
2322         b       get_fs_int_done
2323 get_fs_int_f20:
2324         mfc1    t2, $f20
2325         b       get_fs_int_done
2326 get_fs_int_f22:
2327         mfc1    t2, $f22
2328         b       get_fs_int_done
2329 get_fs_int_f24:
2330         mfc1    t2, $f24
2331         b       get_fs_int_done
2332 get_fs_int_f26:
2333         mfc1    t2, $f26
2334         b       get_fs_int_done
2335 get_fs_int_f28:
2336         mfc1    t2, $f28
2337         b       get_fs_int_done
2338 get_fs_int_f30:
2339         mfc1    t2, $f30
2340 get_fs_int_done:
2341         srl     t0, t2, 31                      # init the sign bit
2342         bge     t2, zero, 1f
2343         negu    t2
2344 1:
2345         j       ra
2346 END(get_fs_int)
2347
2348 /*----------------------------------------------------------------------------
2349  * get_ft_fs_s --
2350  *
2351  *      Read (single precision) the FT register (bits 20-16) and
2352  *      the FS register (bits 15-11) and break up into fields.
2353  *      This is an internal routine used by MipsEmulateFP only.
2354  *
2355  * Results:
2356  *      t0      contains the FS sign
2357  *      t1      contains the FS (biased) exponent
2358  *      t2      contains the FS fraction
2359  *      ta0     contains the FT sign
2360  *      ta1     contains the FT (biased) exponent
2361  *      ta2     contains the FT fraction
2362  *
2363  *----------------------------------------------------------------------------
2364  */
2365 LEAF(get_ft_fs_s)
2366         srl     a3, a0, 17 - 2                  # get FT field (even regs only)
2367         and     a3, a3, 0xF << 2                # mask FT field
2368         lw      a3, get_ft_s_tbl(a3)            # switch on register number
2369         j       a3
2370
2371         .rdata
2372 get_ft_s_tbl:
2373         .word   get_ft_s_f0
2374         .word   get_ft_s_f2
2375         .word   get_ft_s_f4
2376         .word   get_ft_s_f6
2377         .word   get_ft_s_f8
2378         .word   get_ft_s_f10
2379         .word   get_ft_s_f12
2380         .word   get_ft_s_f14
2381         .word   get_ft_s_f16
2382         .word   get_ft_s_f18
2383         .word   get_ft_s_f20
2384         .word   get_ft_s_f22
2385         .word   get_ft_s_f24
2386         .word   get_ft_s_f26
2387         .word   get_ft_s_f28
2388         .word   get_ft_s_f30
2389         .text
2390
2391 get_ft_s_f0:
2392         mfc1    ta0, $f0
2393         b       get_ft_s_done
2394 get_ft_s_f2:
2395         mfc1    ta0, $f2
2396         b       get_ft_s_done
2397 get_ft_s_f4:
2398         mfc1    ta0, $f4
2399         b       get_ft_s_done
2400 get_ft_s_f6:
2401         mfc1    ta0, $f6
2402         b       get_ft_s_done
2403 get_ft_s_f8:
2404         mfc1    ta0, $f8
2405         b       get_ft_s_done
2406 get_ft_s_f10:
2407         mfc1    ta0, $f10
2408         b       get_ft_s_done
2409 get_ft_s_f12:
2410         mfc1    ta0, $f12
2411         b       get_ft_s_done
2412 get_ft_s_f14:
2413         mfc1    ta0, $f14
2414         b       get_ft_s_done
2415 get_ft_s_f16:
2416         mfc1    ta0, $f16
2417         b       get_ft_s_done
2418 get_ft_s_f18:
2419         mfc1    ta0, $f18
2420         b       get_ft_s_done
2421 get_ft_s_f20:
2422         mfc1    ta0, $f20
2423         b       get_ft_s_done
2424 get_ft_s_f22:
2425         mfc1    ta0, $f22
2426         b       get_ft_s_done
2427 get_ft_s_f24:
2428         mfc1    ta0, $f24
2429         b       get_ft_s_done
2430 get_ft_s_f26:
2431         mfc1    ta0, $f26
2432         b       get_ft_s_done
2433 get_ft_s_f28:
2434         mfc1    ta0, $f28
2435         b       get_ft_s_done
2436 get_ft_s_f30:
2437         mfc1    ta0, $f30
2438 get_ft_s_done:
2439         srl     ta1, ta0, 23                    # get exponent
2440         and     ta1, ta1, 0xFF
2441         and     ta2, ta0, 0x7FFFFF              # get fraction
2442         srl     ta0, ta0, 31                    # get sign
2443         bne     ta1, SEXP_INF, 1f               # is it a signaling NAN?
2444         and     v0, ta2, SSIGNAL_NAN
2445         bne     v0, zero, invalid_s
2446 1:
2447         /* fall through to get FS */
2448
2449 /*----------------------------------------------------------------------------
2450  * get_fs_s --
2451  *
2452  *      Read (single precision) the FS register (bits 15-11) and
2453  *      break up into fields.
2454  *      This is an internal routine used by MipsEmulateFP only.
2455  *
2456  * Results:
2457  *      t0      contains the sign
2458  *      t1      contains the (biased) exponent
2459  *      t2      contains the fraction
2460  *
2461  *----------------------------------------------------------------------------
2462  */
2463 ALEAF(get_fs_s)
2464         srl     a3, a0, 12 - 2                  # get FS field (even regs only)
2465         and     a3, a3, 0xF << 2                # mask FS field
2466         lw      a3, get_fs_s_tbl(a3)            # switch on register number
2467         j       a3
2468
2469         .rdata
2470 get_fs_s_tbl:
2471         .word   get_fs_s_f0
2472         .word   get_fs_s_f2
2473         .word   get_fs_s_f4
2474         .word   get_fs_s_f6
2475         .word   get_fs_s_f8
2476         .word   get_fs_s_f10
2477         .word   get_fs_s_f12
2478         .word   get_fs_s_f14
2479         .word   get_fs_s_f16
2480         .word   get_fs_s_f18
2481         .word   get_fs_s_f20
2482         .word   get_fs_s_f22
2483         .word   get_fs_s_f24
2484         .word   get_fs_s_f26
2485         .word   get_fs_s_f28
2486         .word   get_fs_s_f30
2487         .text
2488
2489 get_fs_s_f0:
2490         mfc1    t0, $f0
2491         b       get_fs_s_done
2492 get_fs_s_f2:
2493         mfc1    t0, $f2
2494         b       get_fs_s_done
2495 get_fs_s_f4:
2496         mfc1    t0, $f4
2497         b       get_fs_s_done
2498 get_fs_s_f6:
2499         mfc1    t0, $f6
2500         b       get_fs_s_done
2501 get_fs_s_f8:
2502         mfc1    t0, $f8
2503         b       get_fs_s_done
2504 get_fs_s_f10:
2505         mfc1    t0, $f10
2506         b       get_fs_s_done
2507 get_fs_s_f12:
2508         mfc1    t0, $f12
2509         b       get_fs_s_done
2510 get_fs_s_f14:
2511         mfc1    t0, $f14
2512         b       get_fs_s_done
2513 get_fs_s_f16:
2514         mfc1    t0, $f16
2515         b       get_fs_s_done
2516 get_fs_s_f18:
2517         mfc1    t0, $f18
2518         b       get_fs_s_done
2519 get_fs_s_f20:
2520         mfc1    t0, $f20
2521         b       get_fs_s_done
2522 get_fs_s_f22:
2523         mfc1    t0, $f22
2524         b       get_fs_s_done
2525 get_fs_s_f24:
2526         mfc1    t0, $f24
2527         b       get_fs_s_done
2528 get_fs_s_f26:
2529         mfc1    t0, $f26
2530         b       get_fs_s_done
2531 get_fs_s_f28:
2532         mfc1    t0, $f28
2533         b       get_fs_s_done
2534 get_fs_s_f30:
2535         mfc1    t0, $f30
2536 get_fs_s_done:
2537         srl     t1, t0, 23                      # get exponent
2538         and     t1, t1, 0xFF
2539         and     t2, t0, 0x7FFFFF                # get fraction
2540         srl     t0, t0, 31                      # get sign
2541         bne     t1, SEXP_INF, 1f                # is it a signaling NAN?
2542         and     v0, t2, SSIGNAL_NAN
2543         bne     v0, zero, invalid_s
2544 1:
2545         j       ra
2546 END(get_ft_fs_s)
2547
2548 /*----------------------------------------------------------------------------
2549  * get_ft_fs_d --
2550  *
2551  *      Read (double precision) the FT register (bits 20-16) and
2552  *      the FS register (bits 15-11) and break up into fields.
2553  *      This is an internal routine used by MipsEmulateFP only.
2554  *
2555  * Results:
2556  *      t0      contains the FS sign
2557  *      t1      contains the FS (biased) exponent
2558  *      t2      contains the FS fraction
2559  *      t3      contains the FS remaining fraction
2560  *      ta0     contains the FT sign
2561  *      ta1     contains the FT (biased) exponent
2562  *      ta2     contains the FT fraction
2563  *      ta3     contains the FT remaining fraction
2564  *
2565  *----------------------------------------------------------------------------
2566  */
2567 LEAF(get_ft_fs_d)
2568         srl     a3, a0, 17 - 2                  # get FT field (even regs only)
2569         and     a3, a3, 0xF << 2                # mask FT field
2570         lw      a3, get_ft_d_tbl(a3)            # switch on register number
2571         j       a3
2572
2573         .rdata
2574 get_ft_d_tbl:
2575         .word   get_ft_d_f0
2576         .word   get_ft_d_f2
2577         .word   get_ft_d_f4
2578         .word   get_ft_d_f6
2579         .word   get_ft_d_f8
2580         .word   get_ft_d_f10
2581         .word   get_ft_d_f12
2582         .word   get_ft_d_f14
2583         .word   get_ft_d_f16
2584         .word   get_ft_d_f18
2585         .word   get_ft_d_f20
2586         .word   get_ft_d_f22
2587         .word   get_ft_d_f24
2588         .word   get_ft_d_f26
2589         .word   get_ft_d_f28
2590         .word   get_ft_d_f30
2591         .text
2592
2593 get_ft_d_f0:
2594         mfc1    ta3, $f0
2595         mfc1    ta0, $f1
2596         b       get_ft_d_done
2597 get_ft_d_f2:
2598         mfc1    ta3, $f2
2599         mfc1    ta0, $f3
2600         b       get_ft_d_done
2601 get_ft_d_f4:
2602         mfc1    ta3, $f4
2603         mfc1    ta0, $f5
2604         b       get_ft_d_done
2605 get_ft_d_f6:
2606         mfc1    ta3, $f6
2607         mfc1    ta0, $f7
2608         b       get_ft_d_done
2609 get_ft_d_f8:
2610         mfc1    ta3, $f8
2611         mfc1    ta0, $f9
2612         b       get_ft_d_done
2613 get_ft_d_f10:
2614         mfc1    ta3, $f10
2615         mfc1    ta0, $f11
2616         b       get_ft_d_done
2617 get_ft_d_f12:
2618         mfc1    ta3, $f12
2619         mfc1    ta0, $f13
2620         b       get_ft_d_done
2621 get_ft_d_f14:
2622         mfc1    ta3, $f14
2623         mfc1    ta0, $f15
2624         b       get_ft_d_done
2625 get_ft_d_f16:
2626         mfc1    ta3, $f16
2627         mfc1    ta0, $f17
2628         b       get_ft_d_done
2629 get_ft_d_f18:
2630         mfc1    ta3, $f18
2631         mfc1    ta0, $f19
2632         b       get_ft_d_done
2633 get_ft_d_f20:
2634         mfc1    ta3, $f20
2635         mfc1    ta0, $f21
2636         b       get_ft_d_done
2637 get_ft_d_f22:
2638         mfc1    ta3, $f22
2639         mfc1    ta0, $f23
2640         b       get_ft_d_done
2641 get_ft_d_f24:
2642         mfc1    ta3, $f24
2643         mfc1    ta0, $f25
2644         b       get_ft_d_done
2645 get_ft_d_f26:
2646         mfc1    ta3, $f26
2647         mfc1    ta0, $f27
2648         b       get_ft_d_done
2649 get_ft_d_f28:
2650         mfc1    ta3, $f28
2651         mfc1    ta0, $f29
2652         b       get_ft_d_done
2653 get_ft_d_f30:
2654         mfc1    ta3, $f30
2655         mfc1    ta0, $f31
2656 get_ft_d_done:
2657         srl     ta1, ta0, 20                    # get exponent
2658         and     ta1, ta1, 0x7FF
2659         and     ta2, ta0, 0xFFFFF               # get fraction
2660         srl     ta0, ta0, 31                    # get sign
2661         bne     ta1, DEXP_INF, 1f               # is it a signaling NAN?
2662         and     v0, ta2, DSIGNAL_NAN
2663         bne     v0, zero, invalid_d
2664 1:
2665         /* fall through to get FS */
2666
2667 /*----------------------------------------------------------------------------
2668  * get_fs_d --
2669  *
2670  *      Read (double precision) the FS register (bits 15-11) and
2671  *      break up into fields.
2672  *      This is an internal routine used by MipsEmulateFP only.
2673  *
2674  * Results:
2675  *      t0      contains the sign
2676  *      t1      contains the (biased) exponent
2677  *      t2      contains the fraction
2678  *      t3      contains the remaining fraction
2679  *
2680  *----------------------------------------------------------------------------
2681  */
2682 ALEAF(get_fs_d)
2683         srl     a3, a0, 12 - 2                  # get FS field (even regs only)
2684         and     a3, a3, 0xF << 2                # mask FS field
2685         lw      a3, get_fs_d_tbl(a3)            # switch on register number
2686         j       a3
2687
2688         .rdata
2689 get_fs_d_tbl:
2690         .word   get_fs_d_f0
2691         .word   get_fs_d_f2
2692         .word   get_fs_d_f4
2693         .word   get_fs_d_f6
2694         .word   get_fs_d_f8
2695         .word   get_fs_d_f10
2696         .word   get_fs_d_f12
2697         .word   get_fs_d_f14
2698         .word   get_fs_d_f16
2699         .word   get_fs_d_f18
2700         .word   get_fs_d_f20
2701         .word   get_fs_d_f22
2702         .word   get_fs_d_f24
2703         .word   get_fs_d_f26
2704         .word   get_fs_d_f28
2705         .word   get_fs_d_f30
2706         .text
2707
2708 get_fs_d_f0:
2709         mfc1    t3, $f0
2710         mfc1    t0, $f1
2711         b       get_fs_d_done
2712 get_fs_d_f2:
2713         mfc1    t3, $f2
2714         mfc1    t0, $f3
2715         b       get_fs_d_done
2716 get_fs_d_f4:
2717         mfc1    t3, $f4
2718         mfc1    t0, $f5
2719         b       get_fs_d_done
2720 get_fs_d_f6:
2721         mfc1    t3, $f6
2722         mfc1    t0, $f7
2723         b       get_fs_d_done
2724 get_fs_d_f8:
2725         mfc1    t3, $f8
2726         mfc1    t0, $f9
2727         b       get_fs_d_done
2728 get_fs_d_f10:
2729         mfc1    t3, $f10
2730         mfc1    t0, $f11
2731         b       get_fs_d_done
2732 get_fs_d_f12:
2733         mfc1    t3, $f12
2734         mfc1    t0, $f13
2735         b       get_fs_d_done
2736 get_fs_d_f14:
2737         mfc1    t3, $f14
2738         mfc1    t0, $f15
2739         b       get_fs_d_done
2740 get_fs_d_f16:
2741         mfc1    t3, $f16
2742         mfc1    t0, $f17
2743         b       get_fs_d_done
2744 get_fs_d_f18:
2745         mfc1    t3, $f18
2746         mfc1    t0, $f19
2747         b       get_fs_d_done
2748 get_fs_d_f20:
2749         mfc1    t3, $f20
2750         mfc1    t0, $f21
2751         b       get_fs_d_done
2752 get_fs_d_f22:
2753         mfc1    t3, $f22
2754         mfc1    t0, $f23
2755         b       get_fs_d_done
2756 get_fs_d_f24:
2757         mfc1    t3, $f24
2758         mfc1    t0, $f25
2759         b       get_fs_d_done
2760 get_fs_d_f26:
2761         mfc1    t3, $f26
2762         mfc1    t0, $f27
2763         b       get_fs_d_done
2764 get_fs_d_f28:
2765         mfc1    t3, $f28
2766         mfc1    t0, $f29
2767         b       get_fs_d_done
2768 get_fs_d_f30:
2769         mfc1    t3, $f30
2770         mfc1    t0, $f31
2771 get_fs_d_done:
2772         srl     t1, t0, 20                      # get exponent
2773         and     t1, t1, 0x7FF
2774         and     t2, t0, 0xFFFFF                 # get fraction
2775         srl     t0, t0, 31                      # get sign
2776         bne     t1, DEXP_INF, 1f                # is it a signaling NAN?
2777         and     v0, t2, DSIGNAL_NAN
2778         bne     v0, zero, invalid_d
2779 1:
2780         j       ra
2781 END(get_ft_fs_d)
2782
2783 /*----------------------------------------------------------------------------
2784  * get_cmp_s --
2785  *
2786  *      Read (single precision) the FS register (bits 15-11) and
2787  *      the FT register (bits 20-16) and break up into fields.
2788  *      This is an internal routine used by MipsEmulateFP only.
2789  *
2790  * Results:
2791  *      t0      contains the sign
2792  *      t1      contains the (biased) exponent
2793  *      t2      contains the fraction
2794  *      ta0     contains the sign
2795  *      ta1     contains the (biased) exponent
2796  *      ta2     contains the fraction
2797  *
2798  *----------------------------------------------------------------------------
2799  */
2800 LEAF(get_cmp_s)
2801         srl     a3, a0, 12 - 2                  # get FS field (even regs only)
2802         and     a3, a3, 0xF << 2                # mask FS field
2803         lw      a3, cmp_fs_s_tbl(a3)            # switch on register number
2804         j       a3
2805
2806         .rdata
2807 cmp_fs_s_tbl:
2808         .word   cmp_fs_s_f0
2809         .word   cmp_fs_s_f2
2810         .word   cmp_fs_s_f4
2811         .word   cmp_fs_s_f6
2812         .word   cmp_fs_s_f8
2813         .word   cmp_fs_s_f10
2814         .word   cmp_fs_s_f12
2815         .word   cmp_fs_s_f14
2816         .word   cmp_fs_s_f16
2817         .word   cmp_fs_s_f18
2818         .word   cmp_fs_s_f20
2819         .word   cmp_fs_s_f22
2820         .word   cmp_fs_s_f24
2821         .word   cmp_fs_s_f26
2822         .word   cmp_fs_s_f28
2823         .word   cmp_fs_s_f30
2824         .text
2825
2826 cmp_fs_s_f0:
2827         mfc1    t0, $f0
2828         b       cmp_fs_s_done
2829 cmp_fs_s_f2:
2830         mfc1    t0, $f2
2831         b       cmp_fs_s_done
2832 cmp_fs_s_f4:
2833         mfc1    t0, $f4
2834         b       cmp_fs_s_done
2835 cmp_fs_s_f6:
2836         mfc1    t0, $f6
2837         b       cmp_fs_s_done
2838 cmp_fs_s_f8:
2839         mfc1    t0, $f8
2840         b       cmp_fs_s_done
2841 cmp_fs_s_f10:
2842         mfc1    t0, $f10
2843         b       cmp_fs_s_done
2844 cmp_fs_s_f12:
2845         mfc1    t0, $f12
2846         b       cmp_fs_s_done
2847 cmp_fs_s_f14:
2848         mfc1    t0, $f14
2849         b       cmp_fs_s_done
2850 cmp_fs_s_f16:
2851         mfc1    t0, $f16
2852         b       cmp_fs_s_done
2853 cmp_fs_s_f18:
2854         mfc1    t0, $f18
2855         b       cmp_fs_s_done
2856 cmp_fs_s_f20:
2857         mfc1    t0, $f20
2858         b       cmp_fs_s_done
2859 cmp_fs_s_f22:
2860         mfc1    t0, $f22
2861         b       cmp_fs_s_done
2862 cmp_fs_s_f24:
2863         mfc1    t0, $f24
2864         b       cmp_fs_s_done
2865 cmp_fs_s_f26:
2866         mfc1    t0, $f26
2867         b       cmp_fs_s_done
2868 cmp_fs_s_f28:
2869         mfc1    t0, $f28
2870         b       cmp_fs_s_done
2871 cmp_fs_s_f30:
2872         mfc1    t0, $f30
2873 cmp_fs_s_done:
2874         srl     t1, t0, 23                      # get exponent
2875         and     t1, t1, 0xFF
2876         and     t2, t0, 0x7FFFFF                # get fraction
2877         srl     t0, t0, 31                      # get sign
2878
2879         srl     a3, a0, 17 - 2                  # get FT field (even regs only)
2880         and     a3, a3, 0xF << 2                # mask FT field
2881         lw      a3, cmp_ft_s_tbl(a3)            # switch on register number
2882         j       a3
2883
2884         .rdata
2885 cmp_ft_s_tbl:
2886         .word   cmp_ft_s_f0
2887         .word   cmp_ft_s_f2
2888         .word   cmp_ft_s_f4
2889         .word   cmp_ft_s_f6
2890         .word   cmp_ft_s_f8
2891         .word   cmp_ft_s_f10
2892         .word   cmp_ft_s_f12
2893         .word   cmp_ft_s_f14
2894         .word   cmp_ft_s_f16
2895         .word   cmp_ft_s_f18
2896         .word   cmp_ft_s_f20
2897         .word   cmp_ft_s_f22
2898         .word   cmp_ft_s_f24
2899         .word   cmp_ft_s_f26
2900         .word   cmp_ft_s_f28
2901         .word   cmp_ft_s_f30
2902         .text
2903
2904 cmp_ft_s_f0:
2905         mfc1    ta0, $f0
2906         b       cmp_ft_s_done
2907 cmp_ft_s_f2:
2908         mfc1    ta0, $f2
2909         b       cmp_ft_s_done
2910 cmp_ft_s_f4:
2911         mfc1    ta0, $f4
2912         b       cmp_ft_s_done
2913 cmp_ft_s_f6:
2914         mfc1    ta0, $f6
2915         b       cmp_ft_s_done
2916 cmp_ft_s_f8:
2917         mfc1    ta0, $f8
2918         b       cmp_ft_s_done
2919 cmp_ft_s_f10:
2920         mfc1    ta0, $f10
2921         b       cmp_ft_s_done
2922 cmp_ft_s_f12:
2923         mfc1    ta0, $f12
2924         b       cmp_ft_s_done
2925 cmp_ft_s_f14:
2926         mfc1    ta0, $f14
2927         b       cmp_ft_s_done
2928 cmp_ft_s_f16:
2929         mfc1    ta0, $f16
2930         b       cmp_ft_s_done
2931 cmp_ft_s_f18:
2932         mfc1    ta0, $f18
2933         b       cmp_ft_s_done
2934 cmp_ft_s_f20:
2935         mfc1    ta0, $f20
2936         b       cmp_ft_s_done
2937 cmp_ft_s_f22:
2938         mfc1    ta0, $f22
2939         b       cmp_ft_s_done
2940 cmp_ft_s_f24:
2941         mfc1    ta0, $f24
2942         b       cmp_ft_s_done
2943 cmp_ft_s_f26:
2944         mfc1    ta0, $f26
2945         b       cmp_ft_s_done
2946 cmp_ft_s_f28:
2947         mfc1    ta0, $f28
2948         b       cmp_ft_s_done
2949 cmp_ft_s_f30:
2950         mfc1    ta0, $f30
2951 cmp_ft_s_done:
2952         srl     ta1, ta0, 23                    # get exponent
2953         and     ta1, ta1, 0xFF
2954         and     ta2, ta0, 0x7FFFFF              # get fraction
2955         srl     ta0, ta0, 31                    # get sign
2956         j       ra
2957 END(get_cmp_s)
2958
2959 /*----------------------------------------------------------------------------
2960  * get_cmp_d --
2961  *
2962  *      Read (double precision) the FS register (bits 15-11) and
2963  *      the FT register (bits 20-16) and break up into fields.
2964  *      This is an internal routine used by MipsEmulateFP only.
2965  *
2966  * Results:
2967  *      t0      contains the sign
2968  *      t1      contains the (biased) exponent
2969  *      t2      contains the fraction
2970  *      t3      contains the remaining fraction
2971  *      ta0     contains the sign
2972  *      ta1     contains the (biased) exponent
2973  *      ta2     contains the fraction
2974  *      ta3     contains the remaining fraction
2975  *
2976  *----------------------------------------------------------------------------
2977  */
2978 LEAF(get_cmp_d)
2979         srl     a3, a0, 12 - 2                  # get FS field (even regs only)
2980         and     a3, a3, 0xF << 2                # mask FS field
2981         lw      a3, cmp_fs_d_tbl(a3)            # switch on register number
2982         j       a3
2983
2984         .rdata
2985 cmp_fs_d_tbl:
2986         .word   cmp_fs_d_f0
2987         .word   cmp_fs_d_f2
2988         .word   cmp_fs_d_f4
2989         .word   cmp_fs_d_f6
2990         .word   cmp_fs_d_f8
2991         .word   cmp_fs_d_f10
2992         .word   cmp_fs_d_f12
2993         .word   cmp_fs_d_f14
2994         .word   cmp_fs_d_f16
2995         .word   cmp_fs_d_f18
2996         .word   cmp_fs_d_f20
2997         .word   cmp_fs_d_f22
2998         .word   cmp_fs_d_f24
2999         .word   cmp_fs_d_f26
3000         .word   cmp_fs_d_f28
3001         .word   cmp_fs_d_f30
3002         .text
3003
3004 cmp_fs_d_f0:
3005         mfc1    t3, $f0
3006         mfc1    t0, $f1
3007         b       cmp_fs_d_done
3008 cmp_fs_d_f2:
3009         mfc1    t3, $f2
3010         mfc1    t0, $f3
3011         b       cmp_fs_d_done
3012 cmp_fs_d_f4:
3013         mfc1    t3, $f4
3014         mfc1    t0, $f5
3015         b       cmp_fs_d_done
3016 cmp_fs_d_f6:
3017         mfc1    t3, $f6
3018         mfc1    t0, $f7
3019         b       cmp_fs_d_done
3020 cmp_fs_d_f8:
3021         mfc1    t3, $f8
3022         mfc1    t0, $f9
3023         b       cmp_fs_d_done
3024 cmp_fs_d_f10:
3025         mfc1    t3, $f10
3026         mfc1    t0, $f11
3027         b       cmp_fs_d_done
3028 cmp_fs_d_f12:
3029         mfc1    t3, $f12
3030         mfc1    t0, $f13
3031         b       cmp_fs_d_done
3032 cmp_fs_d_f14:
3033         mfc1    t3, $f14
3034         mfc1    t0, $f15
3035         b       cmp_fs_d_done
3036 cmp_fs_d_f16:
3037         mfc1    t3, $f16
3038         mfc1    t0, $f17
3039         b       cmp_fs_d_done
3040 cmp_fs_d_f18:
3041         mfc1    t3, $f18
3042         mfc1    t0, $f19
3043         b       cmp_fs_d_done
3044 cmp_fs_d_f20:
3045         mfc1    t3, $f20
3046         mfc1    t0, $f21
3047         b       cmp_fs_d_done
3048 cmp_fs_d_f22:
3049         mfc1    t3, $f22
3050         mfc1    t0, $f23
3051         b       cmp_fs_d_done
3052 cmp_fs_d_f24:
3053         mfc1    t3, $f24
3054         mfc1    t0, $f25
3055         b       cmp_fs_d_done
3056 cmp_fs_d_f26:
3057         mfc1    t3, $f26
3058         mfc1    t0, $f27
3059         b       cmp_fs_d_done
3060 cmp_fs_d_f28:
3061         mfc1    t3, $f28
3062         mfc1    t0, $f29
3063         b       cmp_fs_d_done
3064 cmp_fs_d_f30:
3065         mfc1    t3, $f30
3066         mfc1    t0, $f31
3067 cmp_fs_d_done:
3068         srl     t1, t0, 20                      # get exponent
3069         and     t1, t1, 0x7FF
3070         and     t2, t0, 0xFFFFF                 # get fraction
3071         srl     t0, t0, 31                      # get sign
3072
3073         srl     a3, a0, 17 - 2                  # get FT field (even regs only)
3074         and     a3, a3, 0xF << 2                # mask FT field
3075         lw      a3, cmp_ft_d_tbl(a3)            # switch on register number
3076         j       a3
3077
3078         .rdata
3079 cmp_ft_d_tbl:
3080         .word   cmp_ft_d_f0
3081         .word   cmp_ft_d_f2
3082         .word   cmp_ft_d_f4
3083         .word   cmp_ft_d_f6
3084         .word   cmp_ft_d_f8
3085         .word   cmp_ft_d_f10
3086         .word   cmp_ft_d_f12
3087         .word   cmp_ft_d_f14
3088         .word   cmp_ft_d_f16
3089         .word   cmp_ft_d_f18
3090         .word   cmp_ft_d_f20
3091         .word   cmp_ft_d_f22
3092         .word   cmp_ft_d_f24
3093         .word   cmp_ft_d_f26
3094         .word   cmp_ft_d_f28
3095         .word   cmp_ft_d_f30
3096         .text
3097
3098 cmp_ft_d_f0:
3099         mfc1    ta3, $f0
3100         mfc1    ta0, $f1
3101         b       cmp_ft_d_done
3102 cmp_ft_d_f2:
3103         mfc1    ta3, $f2
3104         mfc1    ta0, $f3
3105         b       cmp_ft_d_done
3106 cmp_ft_d_f4:
3107         mfc1    ta3, $f4
3108         mfc1    ta0, $f5
3109         b       cmp_ft_d_done
3110 cmp_ft_d_f6:
3111         mfc1    ta3, $f6
3112         mfc1    ta0, $f7
3113         b       cmp_ft_d_done
3114 cmp_ft_d_f8:
3115         mfc1    ta3, $f8
3116         mfc1    ta0, $f9
3117         b       cmp_ft_d_done
3118 cmp_ft_d_f10:
3119         mfc1    ta3, $f10
3120         mfc1    ta0, $f11
3121         b       cmp_ft_d_done
3122 cmp_ft_d_f12:
3123         mfc1    ta3, $f12
3124         mfc1    ta0, $f13
3125         b       cmp_ft_d_done
3126 cmp_ft_d_f14:
3127         mfc1    ta3, $f14
3128         mfc1    ta0, $f15
3129         b       cmp_ft_d_done
3130 cmp_ft_d_f16:
3131         mfc1    ta3, $f16
3132         mfc1    ta0, $f17
3133         b       cmp_ft_d_done
3134 cmp_ft_d_f18:
3135         mfc1    ta3, $f18
3136         mfc1    ta0, $f19
3137         b       cmp_ft_d_done
3138 cmp_ft_d_f20:
3139         mfc1    ta3, $f20
3140         mfc1    ta0, $f21
3141         b       cmp_ft_d_done
3142 cmp_ft_d_f22:
3143         mfc1    ta3, $f22
3144         mfc1    ta0, $f23
3145         b       cmp_ft_d_done
3146 cmp_ft_d_f24:
3147         mfc1    ta3, $f24
3148         mfc1    ta0, $f25
3149         b       cmp_ft_d_done
3150 cmp_ft_d_f26:
3151         mfc1    ta3, $f26
3152         mfc1    ta0, $f27
3153         b       cmp_ft_d_done
3154 cmp_ft_d_f28:
3155         mfc1    ta3, $f28
3156         mfc1    ta0, $f29
3157         b       cmp_ft_d_done
3158 cmp_ft_d_f30:
3159         mfc1    ta3, $f30
3160         mfc1    ta0, $f31
3161 cmp_ft_d_done:
3162         srl     ta1, ta0, 20                    # get exponent
3163         and     ta1, ta1, 0x7FF
3164         and     ta2, ta0, 0xFFFFF               # get fraction
3165         srl     ta0, ta0, 31                    # get sign
3166         j       ra
3167 END(get_cmp_d)
3168
3169 /*----------------------------------------------------------------------------
3170  * set_fd_s --
3171  *
3172  *      Write (single precision) the FD register (bits 10-6).
3173  *      This is an internal routine used by MipsEmulateFP only.
3174  *
3175  * Arguments:
3176  *      a0      contains the FP instruction
3177  *      t0      contains the sign
3178  *      t1      contains the (biased) exponent
3179  *      t2      contains the fraction
3180  *
3181  * set_fd_word --
3182  *
3183  *      Write (integer) the FD register (bits 10-6).
3184  *      This is an internal routine used by MipsEmulateFP only.
3185  *
3186  * Arguments:
3187  *      a0      contains the FP instruction
3188  *      t2      contains the integer
3189  *
3190  *----------------------------------------------------------------------------
3191  */
3192 LEAF(set_fd_s)
3193         sll     t0, t0, 31                      # position sign
3194         sll     t1, t1, 23                      # position exponent
3195         or      t2, t2, t0
3196         or      t2, t2, t1
3197 ALEAF(set_fd_word)
3198         srl     a3, a0, 7 - 2                   # get FD field (even regs only)
3199         and     a3, a3, 0xF << 2                # mask FT field
3200         lw      a3, set_fd_s_tbl(a3)            # switch on register number
3201         j       a3
3202
3203         .rdata
3204 set_fd_s_tbl:
3205         .word   set_fd_s_f0
3206         .word   set_fd_s_f2
3207         .word   set_fd_s_f4
3208         .word   set_fd_s_f6
3209         .word   set_fd_s_f8
3210         .word   set_fd_s_f10
3211         .word   set_fd_s_f12
3212         .word   set_fd_s_f14
3213         .word   set_fd_s_f16
3214         .word   set_fd_s_f18
3215         .word   set_fd_s_f20
3216         .word   set_fd_s_f22
3217         .word   set_fd_s_f24
3218         .word   set_fd_s_f26
3219         .word   set_fd_s_f28
3220         .word   set_fd_s_f30
3221         .text
3222
3223 set_fd_s_f0:
3224         mtc1    t2, $f0
3225         j       ra
3226 set_fd_s_f2:
3227         mtc1    t2, $f2
3228         j       ra
3229 set_fd_s_f4:
3230         mtc1    t2, $f4
3231         j       ra
3232 set_fd_s_f6:
3233         mtc1    t2, $f6
3234         j       ra
3235 set_fd_s_f8:
3236         mtc1    t2, $f8
3237         j       ra
3238 set_fd_s_f10:
3239         mtc1    t2, $f10
3240         j       ra
3241 set_fd_s_f12:
3242         mtc1    t2, $f12
3243         j       ra
3244 set_fd_s_f14:
3245         mtc1    t2, $f14
3246         j       ra
3247 set_fd_s_f16:
3248         mtc1    t2, $f16
3249         j       ra
3250 set_fd_s_f18:
3251         mtc1    t2, $f18
3252         j       ra
3253 set_fd_s_f20:
3254         mtc1    t2, $f20
3255         j       ra
3256 set_fd_s_f22:
3257         mtc1    t2, $f22
3258         j       ra
3259 set_fd_s_f24:
3260         mtc1    t2, $f24
3261         j       ra
3262 set_fd_s_f26:
3263         mtc1    t2, $f26
3264         j       ra
3265 set_fd_s_f28:
3266         mtc1    t2, $f28
3267         j       ra
3268 set_fd_s_f30:
3269         mtc1    t2, $f30
3270         j       ra
3271 END(set_fd_s)
3272
3273 /*----------------------------------------------------------------------------
3274  * set_fd_d --
3275  *
3276  *      Write (double precision) the FT register (bits 10-6).
3277  *      This is an internal routine used by MipsEmulateFP only.
3278  *
3279  * Arguments:
3280  *      a0      contains the FP instruction
3281  *      t0      contains the sign
3282  *      t1      contains the (biased) exponent
3283  *      t2      contains the fraction
3284  *      t3      contains the remaining fraction
3285  *
3286  *----------------------------------------------------------------------------
3287  */
3288 LEAF(set_fd_d)
3289         sll     t0, t0, 31                      # set sign
3290         sll     t1, t1, 20                      # set exponent
3291         or      t0, t0, t1
3292         or      t0, t0, t2                      # set fraction
3293         srl     a3, a0, 7 - 2                   # get FD field (even regs only)
3294         and     a3, a3, 0xF << 2                # mask FD field
3295         lw      a3, set_fd_d_tbl(a3)            # switch on register number
3296         j       a3
3297
3298         .rdata
3299 set_fd_d_tbl:
3300         .word   set_fd_d_f0
3301         .word   set_fd_d_f2
3302         .word   set_fd_d_f4
3303         .word   set_fd_d_f6
3304         .word   set_fd_d_f8
3305         .word   set_fd_d_f10
3306         .word   set_fd_d_f12
3307         .word   set_fd_d_f14
3308         .word   set_fd_d_f16
3309         .word   set_fd_d_f18
3310         .word   set_fd_d_f20
3311         .word   set_fd_d_f22
3312         .word   set_fd_d_f24
3313         .word   set_fd_d_f26
3314         .word   set_fd_d_f28
3315         .word   set_fd_d_f30
3316         .text
3317
3318 set_fd_d_f0:
3319         mtc1    t3, $f0
3320         mtc1    t0, $f1
3321         j       ra
3322 set_fd_d_f2:
3323         mtc1    t3, $f2
3324         mtc1    t0, $f3
3325         j       ra
3326 set_fd_d_f4:
3327         mtc1    t3, $f4
3328         mtc1    t0, $f5
3329         j       ra
3330 set_fd_d_f6:
3331         mtc1    t3, $f6
3332         mtc1    t0, $f7
3333         j       ra
3334 set_fd_d_f8:
3335         mtc1    t3, $f8
3336         mtc1    t0, $f9
3337         j       ra
3338 set_fd_d_f10:
3339         mtc1    t3, $f10
3340         mtc1    t0, $f11
3341         j       ra
3342 set_fd_d_f12:
3343         mtc1    t3, $f12
3344         mtc1    t0, $f13
3345         j       ra
3346 set_fd_d_f14:
3347         mtc1    t3, $f14
3348         mtc1    t0, $f15
3349         j       ra
3350 set_fd_d_f16:
3351         mtc1    t3, $f16
3352         mtc1    t0, $f17
3353         j       ra
3354 set_fd_d_f18:
3355         mtc1    t3, $f18
3356         mtc1    t0, $f19
3357         j       ra
3358 set_fd_d_f20:
3359         mtc1    t3, $f20
3360         mtc1    t0, $f21
3361         j       ra
3362 set_fd_d_f22:
3363         mtc1    t3, $f22
3364         mtc1    t0, $f23
3365         j       ra
3366 set_fd_d_f24:
3367         mtc1    t3, $f24
3368         mtc1    t0, $f25
3369         j       ra
3370 set_fd_d_f26:
3371         mtc1    t3, $f26
3372         mtc1    t0, $f27
3373         j       ra
3374 set_fd_d_f28:
3375         mtc1    t3, $f28
3376         mtc1    t0, $f29
3377         j       ra
3378 set_fd_d_f30:
3379         mtc1    t3, $f30
3380         mtc1    t0, $f31
3381         j       ra
3382 END(set_fd_d)
3383
3384 /*----------------------------------------------------------------------------
3385  * renorm_fs_s --
3386  *
3387  * Results:
3388  *      t1      unbiased exponent
3389  *      t2      normalized fraction
3390  *
3391  *----------------------------------------------------------------------------
3392  */
3393 LEAF(renorm_fs_s)
3394 /*
3395  * Find out how many leading zero bits are in t2 and put in t9.
3396  */
3397         move    v0, t2
3398         move    t9, zero
3399         srl     v1, v0, 16
3400         bne     v1, zero, 1f
3401         addu    t9, 16
3402         sll     v0, 16
3403 1:
3404         srl     v1, v0, 24
3405         bne     v1, zero, 1f
3406         addu    t9, 8
3407         sll     v0, 8
3408 1:
3409         srl     v1, v0, 28
3410         bne     v1, zero, 1f
3411         addu    t9, 4
3412         sll     v0, 4
3413 1:
3414         srl     v1, v0, 30
3415         bne     v1, zero, 1f
3416         addu    t9, 2
3417         sll     v0, 2
3418 1:
3419         srl     v1, v0, 31
3420         bne     v1, zero, 1f
3421         addu    t9, 1
3422 /*
3423  * Now shift t2 the correct number of bits.
3424  */
3425 1:
3426         subu    t9, t9, SLEAD_ZEROS     # dont count normal leading zeros
3427         li      t1, SEXP_MIN
3428         subu    t1, t1, t9              # adjust exponent
3429         sll     t2, t2, t9
3430         j       ra
3431 END(renorm_fs_s)
3432
3433 /*----------------------------------------------------------------------------
3434  * renorm_fs_d --
3435  *
3436  * Results:
3437  *      t1      unbiased exponent
3438  *      t2,t3   normalized fraction
3439  *
3440  *----------------------------------------------------------------------------
3441  */
3442 LEAF(renorm_fs_d)
3443 /*
3444  * Find out how many leading zero bits are in t2,t3 and put in t9.
3445  */
3446         move    v0, t2
3447         move    t9, zero
3448         bne     t2, zero, 1f
3449         move    v0, t3
3450         addu    t9, 32
3451 1:
3452         srl     v1, v0, 16
3453         bne     v1, zero, 1f
3454         addu    t9, 16
3455         sll     v0, 16
3456 1:
3457         srl     v1, v0, 24
3458         bne     v1, zero, 1f
3459         addu    t9, 8
3460         sll     v0, 8
3461 1:
3462         srl     v1, v0, 28
3463         bne     v1, zero, 1f
3464         addu    t9, 4
3465         sll     v0, 4
3466 1:
3467         srl     v1, v0, 30
3468         bne     v1, zero, 1f
3469         addu    t9, 2
3470         sll     v0, 2
3471 1:
3472         srl     v1, v0, 31
3473         bne     v1, zero, 1f
3474         addu    t9, 1
3475 /*
3476  * Now shift t2,t3 the correct number of bits.
3477  */
3478 1:
3479         subu    t9, t9, DLEAD_ZEROS     # dont count normal leading zeros
3480         li      t1, DEXP_MIN
3481         subu    t1, t1, t9              # adjust exponent
3482         li      v0, 32
3483         blt     t9, v0, 1f
3484         subu    t9, t9, v0              # shift fraction left >= 32 bits
3485         sll     t2, t3, t9
3486         move    t3, zero
3487         j       ra
3488 1:
3489         subu    v0, v0, t9              # shift fraction left < 32 bits
3490         sll     t2, t2, t9
3491         srl     v1, t3, v0
3492         or      t2, t2, v1
3493         sll     t3, t3, t9
3494         j       ra
3495 END(renorm_fs_d)
3496
3497 /*----------------------------------------------------------------------------
3498  * renorm_ft_s --
3499  *
3500  * Results:
3501  *      ta1     unbiased exponent
3502  *      ta2     normalized fraction
3503  *
3504  *----------------------------------------------------------------------------
3505  */
3506 LEAF(renorm_ft_s)
3507 /*
3508  * Find out how many leading zero bits are in ta2 and put in t9.
3509  */
3510         move    v0, ta2
3511         move    t9, zero
3512         srl     v1, v0, 16
3513         bne     v1, zero, 1f
3514         addu    t9, 16
3515         sll     v0, 16
3516 1:
3517         srl     v1, v0, 24
3518         bne     v1, zero, 1f
3519         addu    t9, 8
3520         sll     v0, 8
3521 1:
3522         srl     v1, v0, 28
3523         bne     v1, zero, 1f
3524         addu    t9, 4
3525         sll     v0, 4
3526 1:
3527         srl     v1, v0, 30
3528         bne     v1, zero, 1f
3529         addu    t9, 2
3530         sll     v0, 2
3531 1:
3532         srl     v1, v0, 31
3533         bne     v1, zero, 1f
3534         addu    t9, 1
3535 /*
3536  * Now shift ta2 the correct number of bits.
3537  */
3538 1:
3539         subu    t9, t9, SLEAD_ZEROS     # dont count normal leading zeros
3540         li      ta1, SEXP_MIN
3541         subu    ta1, ta1, t9            # adjust exponent
3542         sll     ta2, ta2, t9
3543         j       ra
3544 END(renorm_ft_s)
3545
3546 /*----------------------------------------------------------------------------
3547  * renorm_ft_d --
3548  *
3549  * Results:
3550  *      ta1     unbiased exponent
3551  *      ta2,ta3 normalized fraction
3552  *
3553  *----------------------------------------------------------------------------
3554  */
3555 LEAF(renorm_ft_d)
3556 /*
3557  * Find out how many leading zero bits are in ta2,ta3 and put in t9.
3558  */
3559         move    v0, ta2
3560         move    t9, zero
3561         bne     ta2, zero, 1f
3562         move    v0, ta3
3563         addu    t9, 32
3564 1:
3565         srl     v1, v0, 16
3566         bne     v1, zero, 1f
3567         addu    t9, 16
3568         sll     v0, 16
3569 1:
3570         srl     v1, v0, 24
3571         bne     v1, zero, 1f
3572         addu    t9, 8
3573         sll     v0, 8
3574 1:
3575         srl     v1, v0, 28
3576         bne     v1, zero, 1f
3577         addu    t9, 4
3578         sll     v0, 4
3579 1:
3580         srl     v1, v0, 30
3581         bne     v1, zero, 1f
3582         addu    t9, 2
3583         sll     v0, 2
3584 1:
3585         srl     v1, v0, 31
3586         bne     v1, zero, 1f
3587         addu    t9, 1
3588 /*
3589  * Now shift ta2,ta3 the correct number of bits.
3590  */
3591 1:
3592         subu    t9, t9, DLEAD_ZEROS     # dont count normal leading zeros
3593         li      ta1, DEXP_MIN
3594         subu    ta1, ta1, t9            # adjust exponent
3595         li      v0, 32
3596         blt     t9, v0, 1f
3597         subu    t9, t9, v0              # shift fraction left >= 32 bits
3598         sll     ta2, ta3, t9
3599         move    ta3, zero
3600         j       ra
3601 1:
3602         subu    v0, v0, t9              # shift fraction left < 32 bits
3603         sll     ta2, ta2, t9
3604         srl     v1, ta3, v0
3605         or      ta2, ta2, v1
3606         sll     ta3, ta3, t9
3607         j       ra
3608 END(renorm_ft_d)