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