summaryrefslogtreecommitdiff
path: root/sys/arch/mips64
diff options
context:
space:
mode:
authorPer Fogelstrom <pefo@cvs.openbsd.org>2004-10-30 14:49:00 +0000
committerPer Fogelstrom <pefo@cvs.openbsd.org>2004-10-30 14:49:00 +0000
commitaac36bb83dfc61652e4d8ba38c6190b2bb760f7d (patch)
tree5b7de0ffc4c172e0e317fb899391a04275ce7f70 /sys/arch/mips64
parent6e175411c627e94b02c1c7ecb6797a74910513f8 (diff)
Make the default boot partition p.
Migrate float exception code to 64 bit. Add a few new "uniplemented".
Diffstat (limited to 'sys/arch/mips64')
-rw-r--r--sys/arch/mips64/mips64/db_machdep.c18
-rw-r--r--sys/arch/mips64/mips64/disksubr.c14
-rw-r--r--sys/arch/mips64/mips64/fp.S2848
-rw-r--r--sys/arch/mips64/mips64/lcore_float.S56
-rw-r--r--sys/arch/mips64/mips64/trap.c10
5 files changed, 1147 insertions, 1799 deletions
diff --git a/sys/arch/mips64/mips64/db_machdep.c b/sys/arch/mips64/mips64/db_machdep.c
index dd6ec07ac3c..7a97b1d8d28 100644
--- a/sys/arch/mips64/mips64/db_machdep.c
+++ b/sys/arch/mips64/mips64/db_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: db_machdep.c,v 1.7 2004/10/20 12:49:15 pefo Exp $ */
+/* $OpenBSD: db_machdep.c,v 1.8 2004/10/30 14:48:59 pefo Exp $ */
/*
* Copyright (c) 1998-2003 Opsycon AB (www.opsycon.se)
@@ -77,14 +77,14 @@ struct db_variable db_regs[] = {
{ "a1", (long *)&ddb_regs.a1, FCN_NULL },
{ "a2", (long *)&ddb_regs.a2, FCN_NULL },
{ "a3", (long *)&ddb_regs.a3, FCN_NULL },
- { "t0", (long *)&ddb_regs.t0, FCN_NULL },
- { "t1", (long *)&ddb_regs.t1, FCN_NULL },
- { "t2", (long *)&ddb_regs.t2, FCN_NULL },
- { "t3", (long *)&ddb_regs.t3, FCN_NULL },
- { "t4", (long *)&ddb_regs.t4, FCN_NULL },
- { "t5", (long *)&ddb_regs.t5, FCN_NULL },
- { "t6", (long *)&ddb_regs.t6, FCN_NULL },
- { "t7", (long *)&ddb_regs.t7, FCN_NULL },
+ { "a4", (long *)&ddb_regs.t0, FCN_NULL },
+ { "a5", (long *)&ddb_regs.t1, FCN_NULL },
+ { "a6", (long *)&ddb_regs.t2, FCN_NULL },
+ { "a7", (long *)&ddb_regs.t3, FCN_NULL },
+ { "t0", (long *)&ddb_regs.t4, FCN_NULL },
+ { "t1", (long *)&ddb_regs.t5, FCN_NULL },
+ { "t2", (long *)&ddb_regs.t6, FCN_NULL },
+ { "t3", (long *)&ddb_regs.t7, FCN_NULL },
{ "s0", (long *)&ddb_regs.s0, FCN_NULL },
{ "s1", (long *)&ddb_regs.s1, FCN_NULL },
{ "s2", (long *)&ddb_regs.s2, FCN_NULL },
diff --git a/sys/arch/mips64/mips64/disksubr.c b/sys/arch/mips64/mips64/disksubr.c
index 8ff5c4b0449..bfafe532c40 100644
--- a/sys/arch/mips64/mips64/disksubr.c
+++ b/sys/arch/mips64/mips64/disksubr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: disksubr.c,v 1.5 2004/08/23 14:24:56 pefo Exp $ */
+/* $OpenBSD: disksubr.c,v 1.6 2004/10/30 14:48:59 pefo Exp $ */
/*
* Copyright (c) 1999 Michael Shalayeff
@@ -848,12 +848,12 @@ void
map_sgi_label(struct disklabel *lp, struct sgilabel *dlp)
{
static struct {int m; int b;} maptab[] = {
- { 0, FS_BSDFFS}, { 1, FS_SWAP}, { 10, FS_BSDFFS},
- { 3, FS_BSDFFS}, { 4, FS_BSDFFS}, { 5, FS_BSDFFS},
- { 6, FS_BSDFFS}, { 7, FS_BSDFFS}, { 8, FS_OTHER},
- { 9, FS_BSDFFS}, { 2, FS_UNUSED}, { 11, FS_BSDFFS},
- { 12, FS_BSDFFS}, { 13, FS_BSDFFS}, { 14, FS_BSDFFS},
- { 15, FS_BSDFFS}
+ { 0, FS_BSDFFS}, { 1, FS_SWAP}, { 10, FS_BSDFFS},
+ { 3, FS_BSDFFS}, { 4, FS_BSDFFS}, { 5, FS_BSDFFS},
+ { 6, FS_BSDFFS}, { 7, FS_BSDFFS}, { 15, FS_OTHER},
+ { 9, FS_BSDFFS}, { 2, FS_UNUSED}, { 11, FS_BSDFFS},
+ { 12, FS_BSDFFS}, { 13, FS_BSDFFS}, { 14, FS_BSDFFS},
+ { 8, FS_BSDFFS}
};
int i;
diff --git a/sys/arch/mips64/mips64/fp.S b/sys/arch/mips64/mips64/fp.S
index ce088991c7a..d5bbef1f140 100644
--- a/sys/arch/mips64/mips64/fp.S
+++ b/sys/arch/mips64/mips64/fp.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: fp.S,v 1.5 2004/09/10 09:32:13 pefo Exp $ */
+/* $OpenBSD: fp.S,v 1.6 2004/10/30 14:48:59 pefo Exp $ */
/*
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* from: @(#)fp.s 8.1 (Berkeley) 6/10/93
- * $Id: fp.S,v 1.5 2004/09/10 09:32:13 pefo Exp $
+ * $Id: fp.S,v 1.6 2004/10/30 14:48:59 pefo Exp $
*/
/*
@@ -62,16 +62,17 @@
#define SFRAC_BITS 23
#define DFRAC_BITS 52
#define SIMPL_ONE 0x00800000
-#define DIMPL_ONE 0x00100000
-#define SLEAD_ZEROS 31 - 23
-#define DLEAD_ZEROS 31 - 20
+#define DIMPL_ONE 0x0010000000000000
+#define SLEAD_ZEROS 63 - 55
+#define DLEAD_ZEROS 63 - 52
#define STICKYBIT 1
-#define GUARDBIT 0x80000000
+#define GUARDBIT 0x0000000080000000
+#define DGUARDBIT 0x8000000000000000
+
#define SSIGNAL_NAN 0x00400000
#define DSIGNAL_NAN 0x00080000
#define SQUIET_NAN 0x003fffff
-#define DQUIET_NAN0 0x0007ffff
-#define DQUIET_NAN1 0xffffffff
+#define DQUIET_NAN 0x0007ffffffffffff
#define INT_MIN 0x80000000
#define INT_MAX 0x7fffffff
@@ -85,7 +86,8 @@
* MipsEmulateFP --
*
* Emulate unimplemented floating point operations.
- * This routine should only be called by MipsFPInterrupt().
+ * This routine should only be called by MipsFPInterrupt()
+ * and only if this is a COP1 instruction.
*
* MipsEmulateFP(instr)
* unsigned instr;
@@ -101,536 +103,294 @@
NON_LEAF(MipsEmulateFP, FRAMESZ(CF_SZ), ra)
PTR_SUB sp, sp, FRAMESZ(CF_SZ)
PTR_S ra, CF_RA_OFFS(sp)
-/*
- * Decode the FMT field (bits 24-21) and FUNCTION field (bits 5-0).
- */
- srl v0, a0, 21 - 2 # get FMT field
- and v0, v0, 0xF << 2 # mask FMT field
- and v1, a0, 0x3F # mask FUNC field
- sll v1, v1, 5 # align for table lookup
- bgt v0, 4 << 2, ill # illegal format
- or v1, v1, v0
- cfc1 a1, FPC_CSR # get exception register
- lw a3, func_fmt_tbl(v1) # switch on FUNC & FMT
+ srl v0, a0, 21 # get FMT field
+ and v0, v0, 0x1f # mask FMT field
+ dla a3, func_s
+ beq v0, 0x10, 1f
+ dla a3, func_d
+ beq v0, 0x11, 1f
+ dla a3, func_w
+ beq v0, 0x14, 1f
+ dla a3, func_l
+ beq v0, 0x15, 1f
+ b ill # illegal format
+
+1:
+ and v1, a0, 0x3f # mask FUNC field
+ sll v1, v1, 3 # align for table lookup
+ daddu v1, a3
+ cfc1 a1, FPC_CSR # get exception register
+ ld a3, (v1) # switch on FUNC & FMT
and a1, a1, ~FPC_EXCEPTION_UNIMPL # clear exception
ctc1 a1, FPC_CSR
j a3
.rdata
-func_fmt_tbl:
- .word add_s # 0
- .word add_d # 0
- .word ill # 0
- .word ill # 0
- .word ill # 0
- .word ill # 0
- .word ill # 0
- .word ill # 0
- .word sub_s # 1
- .word sub_d # 1
- .word ill # 1
- .word ill # 1
- .word ill # 1
- .word ill # 1
- .word ill # 1
- .word ill # 1
- .word mul_s # 2
- .word mul_d # 2
- .word ill # 2
- .word ill # 2
- .word ill # 2
- .word ill # 2
- .word ill # 2
- .word ill # 2
- .word div_s # 3
- .word div_d # 3
- .word ill # 3
- .word ill # 3
- .word ill # 3
- .word ill # 3
- .word ill # 3
- .word ill # 3
- .word ill # 4
- .word ill # 4
- .word ill # 4
- .word ill # 4
- .word ill # 4
- .word ill # 4
- .word ill # 4
- .word ill # 4
- .word abs_s # 5
- .word abs_d # 5
- .word ill # 5
- .word ill # 5
- .word ill # 5
- .word ill # 5
- .word ill # 5
- .word ill # 5
- .word mov_s # 6
- .word mov_d # 6
- .word ill # 6
- .word ill # 6
- .word ill # 6
- .word ill # 6
- .word ill # 6
- .word ill # 6
- .word neg_s # 7
- .word neg_d # 7
- .word ill # 7
- .word ill # 7
- .word ill # 7
- .word ill # 7
- .word ill # 7
- .word ill # 7
- .word ill # 8
- .word ill # 8
- .word ill # 8
- .word ill # 8
- .word ill # 8
- .word ill # 8
- .word ill # 8
- .word ill # 8
- .word ill # 9
- .word ill # 9
- .word ill # 9
- .word ill # 9
- .word ill # 9
- .word ill # 9
- .word ill # 9
- .word ill # 9
- .word ill # 10
- .word ill # 10
- .word ill # 10
- .word ill # 10
- .word ill # 10
- .word ill # 10
- .word ill # 10
- .word ill # 10
- .word ill # 11
- .word ill # 11
- .word ill # 11
- .word ill # 11
- .word ill # 11
- .word ill # 11
- .word ill # 11
- .word ill # 11
- .word ill # 12
- .word ill # 12
- .word ill # 12
- .word ill # 12
- .word ill # 12
- .word ill # 12
- .word ill # 12
- .word ill # 12
- .word ill # 13
- .word ill # 13
- .word ill # 13
- .word ill # 13
- .word ill # 13
- .word ill # 13
- .word ill # 13
- .word ill # 13
- .word ill # 14
- .word ill # 14
- .word ill # 14
- .word ill # 14
- .word ill # 14
- .word ill # 14
- .word ill # 14
- .word ill # 14
- .word ill # 15
- .word ill # 15
- .word ill # 15
- .word ill # 15
- .word ill # 15
- .word ill # 15
- .word ill # 15
- .word ill # 15
- .word ill # 16
- .word ill # 16
- .word ill # 16
- .word ill # 16
- .word ill # 16
- .word ill # 16
- .word ill # 16
- .word ill # 16
- .word ill # 17
- .word ill # 17
- .word ill # 17
- .word ill # 17
- .word ill # 17
- .word ill # 17
- .word ill # 17
- .word ill # 17
- .word ill # 18
- .word ill # 18
- .word ill # 18
- .word ill # 18
- .word ill # 18
- .word ill # 18
- .word ill # 18
- .word ill # 18
- .word ill # 19
- .word ill # 19
- .word ill # 19
- .word ill # 19
- .word ill # 19
- .word ill # 19
- .word ill # 19
- .word ill # 19
- .word ill # 20
- .word ill # 20
- .word ill # 20
- .word ill # 20
- .word ill # 20
- .word ill # 20
- .word ill # 20
- .word ill # 20
- .word ill # 21
- .word ill # 21
- .word ill # 21
- .word ill # 21
- .word ill # 21
- .word ill # 21
- .word ill # 21
- .word ill # 21
- .word ill # 22
- .word ill # 22
- .word ill # 22
- .word ill # 22
- .word ill # 22
- .word ill # 22
- .word ill # 22
- .word ill # 22
- .word ill # 23
- .word ill # 23
- .word ill # 23
- .word ill # 23
- .word ill # 23
- .word ill # 23
- .word ill # 23
- .word ill # 23
- .word ill # 24
- .word ill # 24
- .word ill # 24
- .word ill # 24
- .word ill # 24
- .word ill # 24
- .word ill # 24
- .word ill # 24
- .word ill # 25
- .word ill # 25
- .word ill # 25
- .word ill # 25
- .word ill # 25
- .word ill # 25
- .word ill # 25
- .word ill # 25
- .word ill # 26
- .word ill # 26
- .word ill # 26
- .word ill # 26
- .word ill # 26
- .word ill # 26
- .word ill # 26
- .word ill # 26
- .word ill # 27
- .word ill # 27
- .word ill # 27
- .word ill # 27
- .word ill # 27
- .word ill # 27
- .word ill # 27
- .word ill # 27
- .word ill # 28
- .word ill # 28
- .word ill # 28
- .word ill # 28
- .word ill # 28
- .word ill # 28
- .word ill # 28
- .word ill # 28
- .word ill # 29
- .word ill # 29
- .word ill # 29
- .word ill # 29
- .word ill # 29
- .word ill # 29
- .word ill # 29
- .word ill # 29
- .word ill # 30
- .word ill # 30
- .word ill # 30
- .word ill # 30
- .word ill # 30
- .word ill # 30
- .word ill # 30
- .word ill # 30
- .word ill # 31
- .word ill # 31
- .word ill # 31
- .word ill # 31
- .word ill # 31
- .word ill # 31
- .word ill # 31
- .word ill # 31
- .word ill # 32
- .word cvt_s_d # 32
- .word ill # 32
- .word ill # 32
- .word cvt_s_w # 32
- .word ill # 32
- .word ill # 32
- .word ill # 32
- .word cvt_d_s # 33
- .word ill # 33
- .word ill # 33
- .word ill # 33
- .word cvt_d_w # 33
- .word ill # 33
- .word ill # 33
- .word ill # 33
- .word ill # 34
- .word ill # 34
- .word ill # 34
- .word ill # 34
- .word ill # 34
- .word ill # 34
- .word ill # 34
- .word ill # 34
- .word ill # 35
- .word ill # 35
- .word ill # 35
- .word ill # 35
- .word ill # 35
- .word ill # 35
- .word ill # 35
- .word ill # 35
- .word cvt_w_s # 36
- .word cvt_w_d # 36
- .word ill # 36
- .word ill # 36
- .word ill # 36
- .word ill # 36
- .word ill # 36
- .word ill # 36
- .word ill # 37
- .word ill # 37
- .word ill # 37
- .word ill # 37
- .word ill # 37
- .word ill # 37
- .word ill # 37
- .word ill # 37
- .word ill # 38
- .word ill # 38
- .word ill # 38
- .word ill # 38
- .word ill # 38
- .word ill # 38
- .word ill # 38
- .word ill # 38
- .word ill # 39
- .word ill # 39
- .word ill # 39
- .word ill # 39
- .word ill # 39
- .word ill # 39
- .word ill # 39
- .word ill # 39
- .word ill # 40
- .word ill # 40
- .word ill # 40
- .word ill # 40
- .word ill # 40
- .word ill # 40
- .word ill # 40
- .word ill # 40
- .word ill # 41
- .word ill # 41
- .word ill # 41
- .word ill # 41
- .word ill # 41
- .word ill # 41
- .word ill # 41
- .word ill # 41
- .word ill # 42
- .word ill # 42
- .word ill # 42
- .word ill # 42
- .word ill # 42
- .word ill # 42
- .word ill # 42
- .word ill # 42
- .word ill # 43
- .word ill # 43
- .word ill # 43
- .word ill # 43
- .word ill # 43
- .word ill # 43
- .word ill # 43
- .word ill # 43
- .word ill # 44
- .word ill # 44
- .word ill # 44
- .word ill # 44
- .word ill # 44
- .word ill # 44
- .word ill # 44
- .word ill # 44
- .word ill # 45
- .word ill # 45
- .word ill # 45
- .word ill # 45
- .word ill # 45
- .word ill # 45
- .word ill # 45
- .word ill # 45
- .word ill # 46
- .word ill # 46
- .word ill # 46
- .word ill # 46
- .word ill # 46
- .word ill # 46
- .word ill # 46
- .word ill # 46
- .word ill # 47
- .word ill # 47
- .word ill # 47
- .word ill # 47
- .word ill # 47
- .word ill # 47
- .word ill # 47
- .word ill # 47
- .word cmp_s # 48
- .word cmp_d # 48
- .word ill # 48
- .word ill # 48
- .word ill # 48
- .word ill # 48
- .word ill # 48
- .word ill # 48
- .word cmp_s # 49
- .word cmp_d # 49
- .word ill # 49
- .word ill # 49
- .word ill # 49
- .word ill # 49
- .word ill # 49
- .word ill # 49
- .word cmp_s # 50
- .word cmp_d # 50
- .word ill # 50
- .word ill # 50
- .word ill # 50
- .word ill # 50
- .word ill # 50
- .word ill # 50
- .word cmp_s # 51
- .word cmp_d # 51
- .word ill # 51
- .word ill # 51
- .word ill # 51
- .word ill # 51
- .word ill # 51
- .word ill # 51
- .word cmp_s # 52
- .word cmp_d # 52
- .word ill # 52
- .word ill # 52
- .word ill # 52
- .word ill # 52
- .word ill # 52
- .word ill # 52
- .word cmp_s # 53
- .word cmp_d # 53
- .word ill # 53
- .word ill # 53
- .word ill # 53
- .word ill # 53
- .word ill # 53
- .word ill # 53
- .word cmp_s # 54
- .word cmp_d # 54
- .word ill # 54
- .word ill # 54
- .word ill # 54
- .word ill # 54
- .word ill # 54
- .word ill # 54
- .word cmp_s # 55
- .word cmp_d # 55
- .word ill # 55
- .word ill # 55
- .word ill # 55
- .word ill # 55
- .word ill # 55
- .word ill # 55
- .word cmp_s # 56
- .word cmp_d # 56
- .word ill # 56
- .word ill # 56
- .word ill # 56
- .word ill # 56
- .word ill # 56
- .word ill # 56
- .word cmp_s # 57
- .word cmp_d # 57
- .word ill # 57
- .word ill # 57
- .word ill # 57
- .word ill # 57
- .word ill # 57
- .word ill # 57
- .word cmp_s # 58
- .word cmp_d # 58
- .word ill # 58
- .word ill # 58
- .word ill # 58
- .word ill # 58
- .word ill # 58
- .word ill # 58
- .word cmp_s # 59
- .word cmp_d # 59
- .word ill # 59
- .word ill # 59
- .word ill # 59
- .word ill # 59
- .word ill # 59
- .word ill # 59
- .word cmp_s # 60
- .word cmp_d # 60
- .word ill # 60
- .word ill # 60
- .word ill # 60
- .word ill # 60
- .word ill # 60
- .word ill # 60
- .word cmp_s # 61
- .word cmp_d # 61
- .word ill # 61
- .word ill # 61
- .word ill # 61
- .word ill # 61
- .word ill # 61
- .word ill # 61
- .word cmp_s # 62
- .word cmp_d # 62
- .word ill # 62
- .word ill # 62
- .word ill # 62
- .word ill # 62
- .word ill # 62
- .word ill # 62
- .word cmp_s # 63
- .word cmp_d # 63
- .word ill # 63
- .word ill # 63
- .word ill # 63
- .word ill # 63
- .word ill # 63
- .word ill # 63
+func_s:
+ .dword add_s # 0
+ .dword sub_s # 1
+ .dword mul_s # 2
+ .dword div_s # 3
+ .dword ill # 4
+ .dword abs_s # 5
+ .dword mov_s # 6
+ .dword neg_s # 7
+ .dword ill # 8
+ .dword ill # 9
+ .dword ill # 10
+ .dword ill # 11
+ .dword round_w_s # 12
+ .dword trunc_w_s # 13
+ .dword ceil_w_s # 14
+ .dword floor_w_s # 15
+ .dword ill # 16
+ .dword ill # 17
+ .dword ill # 18
+ .dword ill # 19
+ .dword ill # 20
+ .dword ill # 21
+ .dword ill # 22
+ .dword ill # 23
+ .dword ill # 24
+ .dword ill # 25
+ .dword ill # 26
+ .dword ill # 27
+ .dword ill # 28
+ .dword ill # 29
+ .dword ill # 30
+ .dword ill # 31
+ .dword ill # 32
+ .dword cvt_d_s # 33
+ .dword ill # 34
+ .dword ill # 35
+ .dword cvt_w_s # 36
+ .dword ill # 37
+ .dword ill # 38
+ .dword ill # 39
+ .dword ill # 40
+ .dword ill # 41
+ .dword ill # 42
+ .dword ill # 43
+ .dword ill # 44
+ .dword ill # 45
+ .dword ill # 46
+ .dword ill # 47
+ .dword cmp_s # 48
+ .dword cmp_s # 49
+ .dword cmp_s # 50
+ .dword cmp_s # 51
+ .dword cmp_s # 52
+ .dword cmp_s # 53
+ .dword cmp_s # 54
+ .dword cmp_s # 55
+ .dword cmp_s # 56
+ .dword cmp_s # 57
+ .dword cmp_s # 58
+ .dword cmp_s # 59
+ .dword cmp_s # 60
+ .dword cmp_s # 61
+ .dword cmp_s # 62
+ .dword cmp_s # 63
+
+func_d:
+ .dword add_d # 0
+ .dword sub_d # 1
+ .dword mul_d # 2
+ .dword div_d # 3
+ .dword ill # 4
+ .dword abs_d # 5
+ .dword mov_d # 6
+ .dword neg_d # 7
+ .dword ill # 8
+ .dword ill # 9
+ .dword ill # 10
+ .dword ill # 11
+ .dword round_w_d # 12
+ .dword trunc_w_d # 13
+ .dword ceil_w_d # 14
+ .dword floor_w_d # 15
+ .dword ill # 16
+ .dword ill # 17
+ .dword ill # 18
+ .dword ill # 19
+ .dword ill # 20
+ .dword ill # 21
+ .dword ill # 22
+ .dword ill # 23
+ .dword ill # 24
+ .dword ill # 25
+ .dword ill # 26
+ .dword ill # 27
+ .dword ill # 28
+ .dword ill # 29
+ .dword ill # 30
+ .dword ill # 31
+ .dword cvt_s_d # 32
+ .dword ill # 33
+ .dword ill # 34
+ .dword ill # 35
+ .dword cvt_w_d # 36
+ .dword ill # 37
+ .dword ill # 38
+ .dword ill # 39
+ .dword ill # 40
+ .dword ill # 41
+ .dword ill # 42
+ .dword ill # 43
+ .dword ill # 44
+ .dword ill # 45
+ .dword ill # 46
+ .dword ill # 47
+ .dword cmp_d # 48
+ .dword cmp_d # 49
+ .dword cmp_d # 50
+ .dword cmp_d # 51
+ .dword cmp_d # 52
+ .dword cmp_d # 53
+ .dword cmp_d # 54
+ .dword cmp_d # 55
+ .dword cmp_d # 56
+ .dword cmp_d # 57
+ .dword cmp_d # 58
+ .dword cmp_d # 59
+ .dword cmp_d # 60
+ .dword cmp_d # 61
+ .dword cmp_d # 62
+ .dword cmp_d # 63
+
+func_w:
+ .dword ill # 0
+ .dword ill # 1
+ .dword ill # 2
+ .dword ill # 3
+ .dword ill # 4
+ .dword ill # 5
+ .dword ill # 6
+ .dword ill # 7
+ .dword ill # 8
+ .dword ill # 9
+ .dword ill # 10
+ .dword ill # 11
+ .dword ill # 12
+ .dword ill # 13
+ .dword ill # 14
+ .dword ill # 15
+ .dword ill # 16
+ .dword ill # 17
+ .dword ill # 18
+ .dword ill # 19
+ .dword ill # 20
+ .dword ill # 21
+ .dword ill # 22
+ .dword ill # 23
+ .dword ill # 24
+ .dword ill # 25
+ .dword ill # 26
+ .dword ill # 27
+ .dword ill # 28
+ .dword ill # 29
+ .dword ill # 30
+ .dword ill # 31
+ .dword cvt_s_w # 32
+ .dword cvt_d_w # 33
+ .dword ill # 34
+ .dword ill # 35
+ .dword ill # 36
+ .dword ill # 37
+ .dword ill # 38
+ .dword ill # 39
+ .dword ill # 40
+ .dword ill # 41
+ .dword ill # 42
+ .dword ill # 43
+ .dword ill # 44
+ .dword ill # 45
+ .dword ill # 46
+ .dword ill # 47
+ .dword ill # 48
+ .dword ill # 49
+ .dword ill # 50
+ .dword ill # 51
+ .dword ill # 52
+ .dword ill # 53
+ .dword ill # 54
+ .dword ill # 55
+ .dword ill # 56
+ .dword ill # 57
+ .dword ill # 58
+ .dword ill # 59
+ .dword ill # 60
+ .dword ill # 61
+ .dword ill # 62
+ .dword ill # 63
+
+func_l:
+ .dword ill # 0
+ .dword ill # 1
+ .dword ill # 2
+ .dword ill # 3
+ .dword ill # 4
+ .dword ill # 5
+ .dword ill # 6
+ .dword ill # 7
+ .dword ill # 8
+ .dword ill # 9
+ .dword ill # 10
+ .dword ill # 11
+ .dword ill # 12
+ .dword ill # 13
+ .dword ill # 14
+ .dword ill # 15
+ .dword ill # 16
+ .dword ill # 17
+ .dword ill # 18
+ .dword ill # 19
+ .dword ill # 20
+ .dword ill # 21
+ .dword ill # 22
+ .dword ill # 23
+ .dword ill # 24
+ .dword ill # 25
+ .dword ill # 26
+ .dword ill # 27
+ .dword ill # 28
+ .dword ill # 29
+ .dword ill # 30
+ .dword ill # 31
+ .dword cvt_s_l # 32
+ .dword cvt_d_l # 33
+ .dword ill # 34
+ .dword ill # 35
+ .dword ill # 36
+ .dword ill # 37
+ .dword ill # 38
+ .dword ill # 39
+ .dword ill # 40
+ .dword ill # 41
+ .dword ill # 42
+ .dword ill # 43
+ .dword ill # 44
+ .dword ill # 45
+ .dword ill # 46
+ .dword ill # 47
+ .dword ill # 48
+ .dword ill # 49
+ .dword ill # 50
+ .dword ill # 51
+ .dword ill # 52
+ .dword ill # 53
+ .dword ill # 54
+ .dword ill # 55
+ .dword ill # 56
+ .dword ill # 57
+ .dword ill # 58
+ .dword ill # 59
+ .dword ill # 60
+ .dword ill # 61
+ .dword ill # 62
+ .dword ill # 63
+
.text
/*
@@ -638,7 +398,7 @@ func_fmt_tbl:
*/
sub_s:
jal get_ft_fs_s
- xor ta0, ta0, 1 # negate FT sign bit
+ xor ta0, 1 # negate FT sign bit
b add_sub_s
/*
* Single precision add.
@@ -674,26 +434,26 @@ add_sub_s:
or t0, t0, ta0 # compute result sign
b result_fs_s
1:
- and t0, t0, ta0 # compute result sign
+ and t0, ta0 # compute result sign
b result_fs_s
4:
bne ta1, zero, 2f # is FT a denormalized num?
beq ta2, zero, result_fs_s # FT is zero, result=FS
- subu t1, t1, SEXP_BIAS # unbias FS exponent
- or t2, t2, SIMPL_ONE # set implied one bit
+ subu t1, SEXP_BIAS # unbias FS exponent
+ or t2, SIMPL_ONE # set implied one bit
jal renorm_ft_s
b 5f
2:
- subu t1, t1, SEXP_BIAS # unbias FS exponent
- or t2, t2, SIMPL_ONE # set implied one bit
- subu ta1, ta1, SEXP_BIAS # unbias FT exponent
- or ta2, ta2, SIMPL_ONE # set implied one bit
+ subu t1, SEXP_BIAS # unbias FS exponent
+ or t2, SIMPL_ONE # set implied one bit
+ subu ta1, SEXP_BIAS # unbias FT exponent
+ or ta2, SIMPL_ONE # set implied one bit
/*
* Perform the addition.
*/
5:
move t8, zero # no shifted bits (sticky reg)
- beq t1, ta1, 4f # no shift needed
+ beq t1, ta1, 4f # exp equal, no shift needed
subu v0, t1, ta1 # v0 = difference of exponents
move v1, v0 # v1 = abs(difference)
bge v0, zero, 1f
@@ -765,21 +525,15 @@ add_sub_d:
bne t1, DEXP_INF, 1f # is FS an infinity?
bne ta1, DEXP_INF, result_fs_d # if FT is not inf, result=FS
bne t2, zero, result_fs_d # if FS is NAN, result is FS
- bne t3, zero, result_fs_d
bne ta2, zero, result_ft_d # if FT is NAN, result is FT
- bne ta3, zero, result_ft_d
bne t0, ta0, invalid_d # both infinities same sign?
b result_fs_d # result is in FS
1:
beq ta1, DEXP_INF, result_ft_d # if FT is inf, result=FT
bne t1, zero, 4f # is FS a denormalized num?
- bne t2, zero, 1f # is FS zero?
- beq t3, zero, 3f
-1:
+ beq t2, zero, 3f # is FS zero?
bne ta1, zero, 2f # is FT a denormalized num?
- bne ta2, zero, 1f
- beq ta3, zero, result_fs_d # FT is zero, result=FS
-1:
+ beq ta2, zero, result_fs_d # FT is zero, result=FS
jal renorm_fs_d
jal renorm_ft_d
b 5f
@@ -791,7 +545,6 @@ add_sub_d:
3:
bne ta1, zero, result_ft_d # if FT != 0, result=FT
bne ta2, zero, result_ft_d
- bne ta3, zero, result_ft_d
and v0, a1, FPC_ROUNDING_BITS # get rounding mode
bne v0, FPC_ROUND_RM, 1f # round to -infinity?
or t0, t0, ta0 # compute result sign
@@ -801,9 +554,7 @@ add_sub_d:
b result_fs_d
4:
bne ta1, zero, 2f # is FT a denormalized num?
- bne ta2, zero, 1f
- beq ta3, zero, result_fs_d # FT is zero, result=FS
-1:
+ beq ta2, zero, result_fs_d # FT is zero, result=FS
subu t1, t1, DEXP_BIAS # unbias FS exponent
or t2, t2, DIMPL_ONE # set implied one bit
jal renorm_ft_d
@@ -829,63 +580,30 @@ add_sub_d:
bge v0, zero, 1f # check which exp is larger
move t1, ta1 # result exp is FTs
move t2, zero # FSs fraction shifted is zero
- move t3, zero
b 4f
1:
move ta2, zero # FTs fraction shifted is zero
- move ta3, zero
b 4f
2:
- li t9, 32
+ li t9, 64
+ subu t9, t9, v1
bge v0, zero, 3f # if FS > FT, shift FTs frac
move t1, ta1 # FT > FS, result exp is FTs
- blt v1, t9, 1f # shift right by < 32?
- subu v1, v1, t9
- subu t9, t9, v1
- sll t8, t2, t9 # save bits shifted out
- sltu t9, zero, t3 # dont lose any one bits
- or t8, t8, t9 # save sticky bit
- srl t3, t2, v1 # shift FSs fraction
- move t2, zero
- b 4f
-1:
- subu t9, t9, v1
- sll t8, t3, t9 # save bits shifted out
- srl t3, t3, v1 # shift FSs fraction
- sll t9, t2, t9 # save bits shifted out of t2
- or t3, t3, t9 # and put into t3
- srl t2, t2, v1
+ dsll t8, t2, t9 # save bits shifted out
+ dsrl t2, t2, v1
b 4f
3:
- blt v1, t9, 1f # shift right by < 32?
- subu v1, v1, t9
- subu t9, t9, v1
- sll t8, ta2, t9 # save bits shifted out
- srl ta3, ta2, v1 # shift FTs fraction
- move ta2, zero
- b 4f
-1:
- subu t9, t9, v1
- sll t8, ta3, t9 # save bits shifted out
- srl ta3, ta3, v1 # shift FTs fraction
- sll t9, ta2, t9 # save bits shifted out of t2
- or ta3, ta3, t9 # and put into t3
- srl ta2, ta2, v1
+ dsll t8, ta2, t9 # save bits shifted out
+ dsrl ta2, ta2, v1
4:
bne t0, ta0, 1f # if signs differ, subtract
- addu t3, t3, ta3 # add fractions
- sltu t9, t3, ta3 # compute carry
- addu t2, t2, ta2 # add fractions
- addu t2, t2, t9 # add carry
+ daddu t2, ta2 # add fractions
b norm_d
1:
blt t2, ta2, 3f # subtract larger from smaller
bne t2, ta2, 2f
- bltu t3, ta3, 3f
- bne t3, ta3, 2f # if same, result=0
move t1, zero # result=0
move t2, zero
- move t3, zero
and v0, a1, FPC_ROUNDING_BITS # get rounding mode
bne v0, FPC_ROUND_RM, 1f # round to -infinity?
or t0, t0, ta0 # compute result sign
@@ -894,29 +612,16 @@ add_sub_d:
and t0, t0, ta0 # compute result sign
b result_fs_d
2:
- beq t8, zero, 1f # compute t2:t3:zero - ta2:ta3:t8
- subu t8, zero, t8
- sltu v0, t3, 1 # compute barrow out
- subu t3, t3, 1 # subtract barrow
- subu t2, t2, v0
-1:
- sltu v0, t3, ta3
- subu t3, t3, ta3 # subtract fractions
- subu t2, t2, ta2 # subtract fractions
- subu t2, t2, v0 # subtract barrow
+ sltu t9, zero, t8 # compute t2:zero - ta2:t8
+ dsubu t8, zero, t8
+ dsubu t2, t2, ta2 # subtract fractions
+ dsubu t2, t2, t9 # subtract barrow
b norm_d
3:
move t0, ta0 # sign of result = FTs
- beq t8, zero, 1f # compute ta2:ta3:zero - t2:t3:t8
- subu t8, zero, t8
- sltu v0, ta3, 1 # compute barrow out
- subu ta3, ta3, 1 # subtract barrow
- subu ta2, ta2, v0
-1:
- sltu v0, ta3, t3
- subu t3, ta3, t3 # subtract fractions
- subu t2, ta2, t2 # subtract fractions
- subu t2, t2, v0 # subtract barrow
+ sltu t9, zero, t8
+ dsubu t2, ta2, t2 # subtract fractions
+ dsubu t2, t2, t9 # subtract barrow
b norm_d
/*
@@ -974,29 +679,22 @@ mul_d:
move ta0, t0
bne t1, DEXP_INF, 2f # is FS an infinity?
bne t2, zero, result_fs_d # if FS is a NAN, result=FS
- bne t3, zero, result_fs_d
bne ta1, DEXP_INF, 1f # FS is inf, is FT an infinity?
bne ta2, zero, result_ft_d # if FT is a NAN, result=FT
- bne ta3, zero, result_ft_d
b result_fs_d # result is infinity
1:
bne ta1, zero, result_fs_d # inf * zero? if no, result=FS
bne ta2, zero, result_fs_d
- bne ta3, zero, result_fs_d
b invalid_d # infinity * zero is invalid
2:
bne ta1, DEXP_INF, 1f # FS != inf, is FT an infinity?
bne t1, zero, result_ft_d # zero * inf? if no, result=FT
bne t2, zero, result_ft_d # if FS is a NAN, result=FS
- bne t3, zero, result_ft_d
bne ta2, zero, result_ft_d # if FT is a NAN, result=FT
- bne ta3, zero, result_ft_d
b invalid_d # zero * infinity is invalid
1:
bne t1, zero, 2f # is FS zero?
- bne t2, zero, 1f
- beq t3, zero, result_fs_d # result is zero
-1:
+ beq t2, zero, result_fs_d # result is zero
jal renorm_fs_d
b 3f
2:
@@ -1004,9 +702,7 @@ mul_d:
or t2, t2, DIMPL_ONE # set implied one bit
3:
bne ta1, zero, 2f # is FT zero?
- bne ta2, zero, 1f
- beq ta3, zero, result_ft_d # result is zero
-1:
+ beq ta2, zero, result_ft_d # result is zero
jal renorm_ft_d
b 3f
2:
@@ -1015,38 +711,9 @@ mul_d:
3:
addu t1, t1, ta1 # compute result exponent
addu t1, t1, 12 # ???
- multu t3, ta3 # multiply fractions (low * low)
- move ta0, t2 # free up t2,t3 for result
- move ta1, t3
- mflo a3 # save low order bits
- mfhi t8
- not v0, t8
- multu ta0, ta3 # multiply FS(high) * FT(low)
- mflo v1
- mfhi t3 # init low result
- sltu v0, v0, v1 # compute carry
- addu t8, v1
- multu ta1, ta2 # multiply FS(low) * FT(high)
- addu t3, t3, v0 # add carry
- not v0, t8
- mflo v1
- mfhi t2
- sltu v0, v0, v1
- addu t8, v1
- multu ta0, ta2 # multiply FS(high) * FT(high)
- addu t3, v0
- not v1, t3
- sltu v1, v1, t2
- addu t3, t2
- not v0, t3
+ dmultu t2, ta2 # multiply fractions
+ mflo t8
mfhi t2
- addu t2, v1
- mflo v1
- sltu v0, v0, v1
- addu t2, v0
- addu t3, v1
- sltu a3, zero, a3 # reduce t8,a3 to just t8
- or t8, a3
b norm_d
/*
@@ -1125,26 +792,20 @@ div_d:
move ta0, t0
bne t1, DEXP_INF, 1f # is FS an infinity?
bne t2, zero, result_fs_d # if FS is NAN, result is FS
- bne t3, zero, result_fs_d
bne ta1, DEXP_INF, result_fs_d # is FT an infinity?
bne ta2, zero, result_ft_d # if FT is NAN, result is FT
- bne ta3, zero, result_ft_d
b invalid_d # infinity/infinity is invalid
1:
bne ta1, DEXP_INF, 1f # is FT an infinity?
bne ta2, zero, result_ft_d # if FT is NAN, result is FT
- bne ta3, zero, result_ft_d
move t1, zero # x / infinity is zero
move t2, zero
- move t3, zero
b result_fs_d
1:
bne t1, zero, 2f # is FS zero?
bne t2, zero, 1f
- bne t3, zero, 1f
bne ta1, zero, result_fs_d # FS=zero, is FT zero?
- bne ta2, zero, result_fs_d
- beq ta3, zero, invalid_d # 0 / 0
+ beq ta2, zero, invalid_d # 0 / 0
b result_fs_d # result = zero
1:
jal renorm_fs_d
@@ -1155,14 +816,12 @@ div_d:
3:
bne ta1, zero, 2f # is FT zero?
bne ta2, zero, 1f
- bne ta3, zero, 1f
or a1, a1, FPC_EXCEPTION_DIV0 | FPC_STICKY_DIV0
and v0, a1, FPC_ENABLE_DIV0 # trap enabled?
bne v0, zero, fpe_trap
- ctc1 a1, FPC_CSR # Save exceptions
+ ctc1 a1, FPC_CSR # Save exceptions
li t1, DEXP_INF # result is infinity
move t2, zero
- move t3, zero
b result_fs_d
1:
jal renorm_ft_d
@@ -1175,47 +834,20 @@ div_d:
subu t1, t1, 3 # compensate for result position
li v0, DFRAC_BITS+3 # number of bits to divide
move t8, t2 # init dividend
- move t9, t3
move t2, zero # init result
- move t3, zero
1:
bltu t8, ta2, 3f # is dividend >= divisor?
- bne t8, ta2, 2f
- bltu t9, ta3, 3f
2:
- sltu v1, t9, ta3 # subtract divisor from dividend
- subu t9, t9, ta3
- subu t8, t8, ta2
- subu t8, t8, v1
- or t3, t3, 1 # remember that we did
+ dsubu t8, t8, ta2 # subtract divisor from dividend
+ or t2, t2, 1 # remember that we did
bne t8, zero, 3f # if not done, continue
- bne t9, zero, 3f
- li v1, 32 # shift result to final position
- blt v0, v1, 2f # shift < 32 bits?
- subu v0, v0, v1 # shift by > 32 bits
- sll t2, t3, v0 # shift upper part
- move t3, zero
- b norm_d
-2:
- subu v1, v1, v0 # shift by < 32 bits
- sll t2, t2, v0 # shift upper part
- srl t9, t3, v1 # save bits shifted out
- or t2, t2, t9 # and put into upper part
- sll t3, t3, v0
+ dsll t2, t2, v0 # shift upper part
b norm_d
3:
- sll t8, t8, 1 # shift dividend
- srl v1, t9, 31 # save bit shifted out
- or t8, t8, v1 # and put into upper part
- sll t9, t9, 1
- sll t2, t2, 1 # shift result
- srl v1, t3, 31 # save bit shifted out
- or t2, t2, v1 # and put into upper part
- sll t3, t3, 1
+ dsll t8, t8, 1 # shift dividend
+ dsll t2, t2, 1 # shift result
subu v0, v0, 1 # are we done?
bne v0, zero, 1b # no, continue
- sltu v0, zero, t9 # be sure to save any one bits
- or t8, t8, v0 # from the lower remainder
b norm_d
/*
@@ -1271,15 +903,11 @@ cvt_s_d:
jal get_fs_d
bne t1, DEXP_INF, 1f # is FS an infinity?
li t1, SEXP_INF # convert to single
- sll t2, t2, 3 # convert D fraction to S
- srl t8, t3, 32 - 3
- or t2, t2, t8
+ dsll t2, t2, 3 # convert D fraction to S
b result_fs_s
1:
bne t1, zero, 2f # is FS zero?
- bne t2, zero, 1f
- beq t3, zero, result_fs_s # result=0
-1:
+ beq t2, zero, result_fs_s # result=0
jal renorm_fs_d
subu t1, t1, 3 # correct exp for shift below
b 3f
@@ -1287,17 +915,21 @@ cvt_s_d:
subu t1, t1, DEXP_BIAS # unbias exponent
or t2, t2, DIMPL_ONE # add implied one bit
3:
- sll t2, t2, 3 # convert D fraction to S
- srl t8, t3, 32 - 3
- or t2, t2, t8
- sll t8, t3, 3
+ dsll t2, t2, 3 # convert D fraction to S
b norm_noshift_s
/*
+ * Convert long integer to single.
+ */
+cvt_s_l:
+ jal get_fs_long
+ b cvt_s_int
+/*
* Convert integer to single.
*/
cvt_s_w:
jal get_fs_int
+cvt_s_int:
bne t2, zero, 1f # check for zero
move t1, zero
b result_fs_s
@@ -1307,35 +939,40 @@ cvt_s_w:
1:
move v0, t2
move t9, zero
- srl v1, v0, 16
+ dsrl v1, v0, 32
+ bne v1, zero, 1f
+ addu t9, 32
+ dsll v0, 32
+1:
+ dsrl v1, v0, 16
bne v1, zero, 1f
addu t9, 16
- sll v0, 16
+ dsll v0, 16
1:
- srl v1, v0, 24
+ dsrl v1, v0, 24
bne v1, zero, 1f
addu t9, 8
- sll v0, 8
+ dsll v0, 8
1:
- srl v1, v0, 28
+ dsrl v1, v0, 28
bne v1, zero, 1f
addu t9, 4
- sll v0, 4
+ dsll v0, 4
1:
- srl v1, v0, 30
+ dsrl v1, v0, 30
bne v1, zero, 1f
addu t9, 2
- sll v0, 2
+ dsll v0, 2
1:
- srl v1, v0, 31
+ dsrl v1, v0, 31
bne v1, zero, 1f
addu t9, 1
/*
* Now shift t2 the correct number of bits.
*/
1:
- subu t9, t9, SLEAD_ZEROS # dont count leading zeros
- li t1, 23 # init exponent
+ subu t9, SLEAD_ZEROS # dont count leading zeros
+ li t1, 23+32 # init exponent
subu t1, t1, t9 # compute exponent
beq t9, zero, 1f
li v0, 32
@@ -1358,7 +995,7 @@ cvt_s_w:
*/
cvt_d_s:
jal get_fs_s
- move t3, zero
+ dsll t2, 32
bne t1, SEXP_INF, 1f # is FS an infinity?
li t1, DEXP_INF # convert to double
b result_fs_d
@@ -1370,18 +1007,23 @@ cvt_d_s:
b norm_d
2:
addu t1, t1, DEXP_BIAS - SEXP_BIAS # bias exponent correctly
- sll t3, t2, 32 - 3 # convert S fraction to D
- srl t2, t2, 3
+ dsrl t2, t2, 3
b result_fs_d
/*
+ * Convert long integer to double.
+ */
+cvt_d_l:
+ jal get_fs_long
+ b cvt_d_int
+/*
* Convert integer to double.
*/
cvt_d_w:
jal get_fs_int
+cvt_d_int:
bne t2, zero, 1f # check for zero
move t1, zero # result=0
- move t3, zero
b result_fs_d
/*
* Find out how many leading zero bits are in t2 and put in t9.
@@ -1389,27 +1031,32 @@ cvt_d_w:
1:
move v0, t2
move t9, zero
- srl v1, v0, 16
+ dsrl v1, v0, 32
+ bne v1, zero, 1f
+ addu t9, 32
+ dsll v0, 32
+1:
+ dsrl v1, v0, 16
bne v1, zero, 1f
addu t9, 16
- sll v0, 16
+ dsll v0, 16
1:
- srl v1, v0, 24
+ dsrl v1, v0, 24
bne v1, zero, 1f
addu t9, 8
- sll v0, 8
+ dsll v0, 8
1:
- srl v1, v0, 28
+ dsrl v1, v0, 28
bne v1, zero, 1f
addu t9, 4
- sll v0, 4
+ dsll v0, 4
1:
- srl v1, v0, 30
+ dsrl v1, v0, 30
bne v1, zero, 1f
addu t9, 2
- sll v0, 2
+ dsll v0, 2
1:
- srl v1, v0, 31
+ dsrl v1, v0, 31
bne v1, zero, 1f
addu t9, 1
/*
@@ -1420,26 +1067,42 @@ cvt_d_w:
li t1, DEXP_BIAS + 20 # init exponent
subu t1, t1, t9 # compute exponent
beq t9, zero, 1f
- li v0, 32
+ li v0, 64
blt t9, zero, 2f # if shift < 0, shift right
subu v0, v0, t9
- sll t2, t2, t9 # shift left
+ dsll t2, t2, t9 # shift left
1:
and t2, t2, ~DIMPL_ONE # clear implied one bit
- move t3, zero
b result_fs_d
2:
negu t9 # shift right by t9
subu v0, v0, t9
- sll t3, t2, v0
- srl t2, t2, t9
+ dsrl t2, t2, t9
and t2, t2, ~DIMPL_ONE # clear implied one bit
b result_fs_d
/*
+ * Convert single to integer with specific rounding.
+ */
+round_w_s:
+ li t3, FPC_ROUND_RN
+ b do_cvt_w_s
+trunc_w_s:
+ li t3, FPC_ROUND_RZ
+ b do_cvt_w_s
+ceil_w_s:
+ li t3, FPC_ROUND_RP
+ b do_cvt_w_s
+floor_w_s:
+ li t3, FPC_ROUND_RM
+ b do_cvt_w_s
+
+/*
* Convert single to integer.
*/
cvt_w_s:
+ and t3, a1, FPC_ROUNDING_BITS # get rounding mode
+do_cvt_w_s:
jal get_fs_s
bne t1, SEXP_INF, 1f # is FS an infinity?
bne t2, zero, invalid_w # invalid conversion
@@ -1451,23 +1114,37 @@ cvt_w_s:
1:
subu t1, t1, SEXP_BIAS # unbias exponent
or t2, t2, SIMPL_ONE # add implied one bit
- sll t3, t2, 32 - 3 # convert S fraction to D
- srl t2, t2, 3
+ dsll t2, t2, 32 - 3 # convert S fraction to D
b cvt_w
/*
+ * Convert single to integer with specific rounding.
+ */
+round_w_d:
+ li t3, FPC_ROUND_RN
+ b do_cvt_w_d
+trunc_w_d:
+ li t3, FPC_ROUND_RZ
+ b do_cvt_w_d
+ceil_w_d:
+ li t3, FPC_ROUND_RP
+ b do_cvt_w_d
+floor_w_d:
+ li t3, FPC_ROUND_RM
+ b do_cvt_w_d
+
+/*
* Convert double to integer.
*/
cvt_w_d:
+ and t3, a1, FPC_ROUNDING_BITS # get rounding mode
+do_cvt_w_d:
jal get_fs_d
bne t1, DEXP_INF, 1f # is FS an infinity?
bne t2, zero, invalid_w # invalid conversion
- bne t3, zero, invalid_w # invalid conversion
1:
bne t1, zero, 2f # is FS zero?
- bne t2, zero, 1f
- beq t3, zero, result_fs_w # result is zero
-1:
+ beq t2, zero, result_fs_w # result is zero
move t2, zero # result is an inexact zero
b inexact_w
2:
@@ -1480,62 +1157,50 @@ cvt_w:
bne t1, v0, 1f # special check for INT_MIN
beq t0, zero, overflow_w # if positive, overflow
bne t2, DIMPL_ONE, overflow_w
- bne t3, zero, overflow_w
li t2, INT_MIN # result is INT_MIN
b result_fs_w
1:
subu v0, t1, 20 # compute amount to shift
beq v0, zero, 2f # is shift needed?
- li v1, 32
+ li v1, 64
blt v0, zero, 1f # if shift < 0, shift right
subu v1, v1, v0 # shift left
- sll t2, t2, v0
- srl t9, t3, v1 # save bits shifted out of t3
- or t2, t2, t9 # and put into t2
- sll t3, t3, v0 # shift FSs fraction
+ dsll t2, t2, v0
b 2f
1:
negu v0 # shift right by v0
subu v1, v1, v0
- sll t8, t3, v1 # save bits shifted out
+ dsll t8, t2, v1 # save bits shifted out
sltu t8, zero, t8 # dont lose any ones
- srl t3, t3, v0 # shift FSs fraction
- or t3, t3, t8
- sll t9, t2, v1 # save bits shifted out of t2
- or t3, t3, t9 # and put into t3
- srl t2, t2, v0
+ dsrl t2, t2, v0
/*
- * round result (t0 is sign, t2 is integer part, t3 is fractional part).
+ * round (t0 is sign, t2:63-32 is integer part, t2:31-0 is fractional part).
*/
2:
- and v0, a1, FPC_ROUNDING_BITS # get rounding mode
- beq v0, FPC_ROUND_RN, 3f # round to nearest
- beq v0, FPC_ROUND_RZ, 5f # round to zero (truncate)
- beq v0, FPC_ROUND_RP, 1f # round to +infinity
+ beq t3, FPC_ROUND_RN, 3f # round to nearest
+ beq t3, FPC_ROUND_RZ, 5f # round to zero (truncate)
+ beq t3, FPC_ROUND_RP, 1f # round to +infinity
beq t0, zero, 5f # if sign is positive, truncate
b 2f
1:
bne t0, zero, 5f # if sign is negative, truncate
2:
- beq t3, zero, 5f # if no fraction bits, continue
- addu t2, t2, 1 # add rounding bit
+ daddu t2, t2, GUARDBIT # add in fractional
blt t2, zero, overflow_w # overflow?
b 5f
3:
- li v0, GUARDBIT # load guard bit for rounding
- addu v0, v0, t3 # add remainder
- sltu v1, v0, t3 # compute carry out
- beq v1, zero, 4f # if no carry, continue
- addu t2, t2, 1 # add carry to result
+ daddu t2, t2, GUARDBIT # add in fractional
blt t2, zero, overflow_w # overflow?
4:
bne v0, zero, 5f # if rounded remainder is zero
- and t2, t2, ~1 # clear LSB (round to nearest)
+ and t2, 0xfffffffe00000000 # clear LSB (round to nearest)
5:
beq t0, zero, 1f # result positive?
negu t2 # convert to negative integer
1:
- beq t3, zero, result_fs_w # is result exact?
+ dsll v0, 32 # save fraction
+ dsrl t2, 32 # shift out fractional part
+ beq v0, zero, result_fs_w # is result exact?
/*
* Handle inexact exception.
*/
@@ -1606,39 +1271,25 @@ cmp_s:
cmp_d:
jal get_cmp_d
bne t1, DEXP_INF, 1f # is FS an infinity?
- bne t2, zero, unordered
- bne t3, zero, unordered # FS is a NAN
+ bne t2, zero, unordered # FS is a NAN
1:
bne ta1, DEXP_INF, 2f # is FT an infinity?
- bne ta2, zero, unordered
- bne ta3, zero, unordered # FT is a NAN
+ bne ta2, zero, unordered # FT is a NAN
2:
- sll t1, t1, 20 # reassemble exp & frac
+ dsll t1, t1, 52 # reassemble exp & frac
or t1, t1, t2
- sll ta1, ta1, 20 # reassemble exp & frac
+ dsll ta1, ta1, 52 # reassemble exp & frac
or ta1, ta1, ta2
beq t0, zero, 1f # is FS positive?
- not t3 # negate t1,t3
- not t1
- addu t3, t3, 1
- seq v0, t3, zero # compute carry
- addu t1, t1, v0
+ dnegu t1 # negate t1
1:
beq ta0, zero, 1f # is FT positive?
- not ta3 # negate ta1,ta3
- not ta1
- addu ta3, ta3, 1
- seq v0, ta3, zero # compute carry
- addu ta1, ta1, v0
+ dnegu ta1
1:
li v0, COND_LESS
blt t1, ta1, test_cond # is FS(MSW) < FT(MSW)?
- move v0, zero
- bne t1, ta1, test_cond # is FS(MSW) > FT(MSW)?
- li v0, COND_LESS
- bltu t3, ta3, test_cond # is FS(LSW) < FT(LSW)?
li v0, COND_EQUAL
- beq t3, ta3, test_cond # is FS(LSW) == FT(LSW)?
+ beq t1, ta1, test_cond # is FS(LSW) == FT(LSW)?
move v0, zero # FS > FT
test_cond:
and v0, v0, a0 # condition match instruction?
@@ -1902,81 +1553,62 @@ underflow_s:
norm_d:
move v0, t2
move t9, zero # t9 = num of leading zeros
- bne t2, zero, 1f
- move v0, t3
- addu t9, 32
- bne t3, zero, 1f
- move v0, t8
+ dsrl v1, v0, 32
+ bne v1, zero, 1f
addu t9, 32
+ dsll v0, 32
1:
- srl v1, v0, 16
+ dsrl v1, v0, 16
bne v1, zero, 1f
addu t9, 16
- sll v0, 16
+ dsll v0, 16
1:
- srl v1, v0, 24
+ dsrl v1, v0, 24
bne v1, zero, 1f
addu t9, 8
- sll v0, 8
+ dsll v0, 8
1:
- srl v1, v0, 28
+ dsrl v1, v0, 28
bne v1, zero, 1f
addu t9, 4
- sll v0, 4
+ dsll v0, 4
1:
- srl v1, v0, 30
+ dsrl v1, v0, 30
bne v1, zero, 1f
addu t9, 2
- sll v0, 2
+ dsll v0, 2
1:
- srl v1, v0, 31
+ dsrl v1, v0, 31
bne v1, zero, 1f
addu t9, 1
/*
- * Now shift t2,t3,t8 the correct number of bits.
+ * Now shift t2,t8 the correct number of bits.
*/
1:
subu t9, t9, DLEAD_ZEROS # dont count leading zeros
subu t1, t1, t9 # adjust the exponent
beq t9, zero, norm_noshift_d
- li v1, 32
+ li v1, 64
blt t9, zero, 2f # if shift < 0, shift right
- blt t9, v1, 1f # shift by < 32?
- subu t9, t9, v1 # shift by >= 32
subu v1, v1, t9
- sll t2, t3, t9 # shift left by t9
- srl v0, t8, v1 # save bits shifted out
+ dsll t2, t2, t9 # shift left by t9
+ dsrl v0, t8, v1 # save bits shifted out
or t2, t2, v0
- sll t3, t8, t9
- move t8, zero
- b norm_noshift_d
-1:
- subu v1, v1, t9
- sll t2, t2, t9 # shift left by t9
- srl v0, t3, v1 # save bits shifted out
- or t2, t2, v0
- sll t3, t3, t9
- srl v0, t8, v1 # save bits shifted out
- or t3, t3, v0
- sll t8, t8, t9
+ dsll t8, t8, t9
b norm_noshift_d
2:
negu t9 # shift right by t9
subu v1, v1, t9 # (known to be < 32 bits)
- sll v0, t8, v1 # save bits shifted out
+ dsll v0, t8, v1 # save bits shifted out
sltu v0, zero, v0 # be sure to save any one bits
- srl t8, t8, t9
+ dsrl t8, t8, t9
or t8, t8, v0
- sll v0, t3, v1 # save bits shifted out
+ dsll v0, t2, v1 # save bits shifted out
or t8, t8, v0
- srl t3, t3, t9
- sll v0, t2, v1 # save bits shifted out
- or t3, t3, v0
- srl t2, t2, t9
+ dsrl t2, t2, t9
norm_noshift_d:
move ta1, t1 # save unrounded exponent
move ta2, t2 # save unrounded fraction (MS)
- move ta3, t3 # save unrounded fraction (LS)
and v0, a1, FPC_ROUNDING_BITS # get rounding mode
beq v0, FPC_ROUND_RN, 3f # round to nearest
beq v0, FPC_ROUND_RZ, 5f # round to zero (truncate)
@@ -1987,27 +1619,23 @@ norm_noshift_d:
bne t0, zero, 5f # if sign is negative, truncate
2:
beq t8, zero, 5f # if exact, continue
- addu t3, t3, 1 # add rounding bit
- bne t3, zero, 5f # branch if no carry
- addu t2, t2, 1 # add carry
+ daddu t2, t2, 1 # add rounding bit
bne t2, DIMPL_ONE<<1, 5f # need to adjust exponent?
addu t1, t1, 1 # adjust exponent
- srl t2, t2, 1 # renormalize fraction
+ dsrl t2, t2, 1 # renormalize fraction
b 5f
3:
- li v0, GUARDBIT # load guard bit for rounding
+ dli v0, DGUARDBIT # load guard bit for rounding
addu v0, v0, t8 # add remainder
sltu v1, v0, t8 # compute carry out
beq v1, zero, 4f # branch if no carry
- addu t3, t3, 1 # add carry
- bne t3, zero, 4f # branch if no carry
- addu t2, t2, 1 # add carry to result
+ daddu t2, t2, 1 # add carry to result
bne t2, DIMPL_ONE<<1, 4f # need to adjust exponent?
addu t1, t1, 1 # adjust exponent
srl t2, t2, 1 # renormalize fraction
4:
bne v0, zero, 5f # if rounded remainder is zero
- and t3, t3, ~1 # clear LSB (round to nearest)
+ and t2, t2, ~1 # clear LSB (round to nearest)
5:
bgt t1, DEXP_MAX, overflow_d # overflow?
blt t1, DEXP_MIN, underflow_d # underflow?
@@ -2051,15 +1679,13 @@ overflow_d:
bne t0, zero, 3f
1:
li t1, DEXP_MAX # result is max finite
- li t2, 0x000fffff
- li t3, 0xffffffff
+ dli t2, 0x000fffffffffffff
b inexact_d
2:
bne t0, zero, 1b
3:
li t1, DEXP_MAX + 1 # result is infinity
move t2, zero
- move t3, zero
b inexact_d
/*
@@ -2084,13 +1710,11 @@ underflow_d:
1:
move t1, ta1 # get unrounded exponent
move t2, ta2 # get unrounded fraction (MS)
- move t3, ta3 # get unrounded fraction (LS)
li t9, DEXP_MIN # compute shift amount
subu t9, t9, t1 # shift t2,t8 right by t9
blt t9, DFRAC_BITS+2, 3f # shift all the bits out?
move t1, zero # result is inexact zero
move t2, zero
- move t3, zero
or a1, a1, FPC_EXCEPTION_UNDERFLOW | FPC_STICKY_UNDERFLOW
/*
* Now round the zero result.
@@ -2105,32 +1729,18 @@ underflow_d:
1:
bne t0, zero, inexact_nobias_d # if sign is negative, truncate
2:
- addu t3, t3, 1 # add rounding bit
+ daddu t2, t2, 1 # add rounding bit
b inexact_nobias_d
3:
- li v1, 32
- blt t9, v1, 1f # shift by < 32?
- subu t9, t9, v1 # shift right by >= 32
+ li v1, 64
subu v1, v1, t9
sltu v0, zero, t8 # be sure to save any one bits
- sll t8, t2, v1 # save bits shifted out
- or t8, t8, v0 # include sticky bits
- srl t3, t2, t9
- move t2, zero
- b 2f
-1:
- subu v1, v1, t9 # shift right by t9
- sltu v0, zero, t8 # be sure to save any one bits
- sll t8, t3, v1 # save bits shifted out
+ dsll t8, t2, v1 # save bits shifted out
or t8, t8, v0 # include sticky bits
- srl t3, t3, t9
- sll v0, t2, v1 # save bits shifted out
- or t3, t3, v0
- srl t2, t2, t9
+ dsrl t2, t2, t9
/*
* Now round the denormalized result.
*/
-2:
and v0, a1, FPC_ROUNDING_BITS # get rounding mode
beq v0, FPC_ROUND_RN, 3f # round to nearest
beq v0, FPC_ROUND_RZ, 5f # round to zero (truncate)
@@ -2141,21 +1751,17 @@ underflow_d:
bne t0, zero, 5f # if sign is negative, truncate
2:
beq t8, zero, 5f # if exact, continue
- addu t3, t3, 1 # add rounding bit
- bne t3, zero, 5f # if no carry, continue
- addu t2, t2, 1 # add carry
+ daddu t2, t2, 1 # add rounding bit
b 5f
3:
- li v0, GUARDBIT # load guard bit for rounding
- addu v0, v0, t8 # add remainder
+ dli v0, DGUARDBIT # load guard bit for rounding
+ daddu v0, v0, t8 # add remainder
sltu v1, v0, t8 # compute carry out
beq v1, zero, 4f # if no carry, continue
- addu t3, t3, 1 # add rounding bit
- bne t3, zero, 4f # if no carry, continue
- addu t2, t2, 1 # add carry
+ daddu t2, t2, 1 # add carry
4:
bne v0, zero, 5f # if rounded remainder is zero
- and t3, t3, ~1 # clear LSB (round to nearest)
+ and t2, t2, ~1 # clear LSB (round to nearest)
5:
move t1, zero # denorm or zero exponent
jal set_fd_d # save result
@@ -2193,9 +1799,8 @@ invalid_d: # trap invalid operation
ctc1 a1, FPC_CSR # save exceptions
move t0, zero # result is a quiet NAN
li t1, DEXP_INF
- li t2, DQUIET_NAN0
- li t3, DQUIET_NAN1
- jal set_fd_d # save result (in t0,t1,t2,t3)
+ dli t2, DQUIET_NAN
+ jal set_fd_d # save result (in t0,t1,t2)
b done
/*
@@ -2206,7 +1811,7 @@ invalid_w: # trap invalid operation
or a1, a1, FPC_EXCEPTION_INVALID | FPC_STICKY_INVALID
and v0, a1, FPC_ENABLE_INVALID
bne v0, zero, fpe_trap
- ctc1 a1, FPC_CSR # save exceptions
+ ctc1 a1, FPC_CSR # save exceptions
bne t0, zero, 1f
li t2, INT_MAX # result is INT_MAX
b result_fs_w
@@ -2248,9 +1853,8 @@ result_ft_d:
move t0, ta0 # result is FT
move t1, ta1
move t2, ta2
- move t3, ta3
result_fs_d: # result is FS
- jal set_fd_d # save result (in t0,t1,t2,t3)
+ jal set_fd_d # save result (in t0,t1,t2)
done:
li v0, 0
@@ -2272,88 +1876,139 @@ END(MipsEmulateFP)
*
*----------------------------------------------------------------------------
*/
+#define GET_FS_INT(n) \
+ .rdata; \
+ .dword get_fs_int_/**/n; \
+ .text; \
+get_fs_int_/**/n: \
+ mfc1 t2, $/**/n; \
+ b get_fs_int_done
+
LEAF(get_fs_int, 0)
- srl a3, a0, 12 - 2 # get FS field (even regs only)
- and a3, a3, 0xF << 2 # mask FS field
- lw a3, get_fs_int_tbl(a3) # switch on register number
+ srl a3, a0, 11 - 3 # get FS field
+ and a3, a3, 0x1f << 3 # mask FS field
+ ld a3, get_fs_int_tbl(a3) # switch on register number
j a3
.rdata
get_fs_int_tbl:
- .word get_fs_int_f0
- .word get_fs_int_f2
- .word get_fs_int_f4
- .word get_fs_int_f6
- .word get_fs_int_f8
- .word get_fs_int_f10
- .word get_fs_int_f12
- .word get_fs_int_f14
- .word get_fs_int_f16
- .word get_fs_int_f18
- .word get_fs_int_f20
- .word get_fs_int_f22
- .word get_fs_int_f24
- .word get_fs_int_f26
- .word get_fs_int_f28
- .word get_fs_int_f30
.text
-get_fs_int_f0:
- mfc1 t2, $f0
- b get_fs_int_done
-get_fs_int_f2:
- mfc1 t2, $f2
- b get_fs_int_done
-get_fs_int_f4:
- mfc1 t2, $f4
- b get_fs_int_done
-get_fs_int_f6:
- mfc1 t2, $f6
- b get_fs_int_done
-get_fs_int_f8:
- mfc1 t2, $f8
- b get_fs_int_done
-get_fs_int_f10:
- mfc1 t2, $f10
- b get_fs_int_done
-get_fs_int_f12:
- mfc1 t2, $f12
- b get_fs_int_done
-get_fs_int_f14:
- mfc1 t2, $f14
- b get_fs_int_done
-get_fs_int_f16:
- mfc1 t2, $f16
- b get_fs_int_done
-get_fs_int_f18:
- mfc1 t2, $f18
- b get_fs_int_done
-get_fs_int_f20:
- mfc1 t2, $f20
- b get_fs_int_done
-get_fs_int_f22:
- mfc1 t2, $f22
- b get_fs_int_done
-get_fs_int_f24:
- mfc1 t2, $f24
- b get_fs_int_done
-get_fs_int_f26:
- mfc1 t2, $f26
- b get_fs_int_done
-get_fs_int_f28:
- mfc1 t2, $f28
- b get_fs_int_done
-get_fs_int_f30:
- mfc1 t2, $f30
+ GET_FS_INT(f0)
+ GET_FS_INT(f1)
+ GET_FS_INT(f2)
+ GET_FS_INT(f3)
+ GET_FS_INT(f4)
+ GET_FS_INT(f5)
+ GET_FS_INT(f6)
+ GET_FS_INT(f7)
+ GET_FS_INT(f8)
+ GET_FS_INT(f9)
+ GET_FS_INT(f10)
+ GET_FS_INT(f11)
+ GET_FS_INT(f12)
+ GET_FS_INT(f13)
+ GET_FS_INT(f14)
+ GET_FS_INT(f15)
+ GET_FS_INT(f16)
+ GET_FS_INT(f17)
+ GET_FS_INT(f18)
+ GET_FS_INT(f19)
+ GET_FS_INT(f20)
+ GET_FS_INT(f21)
+ GET_FS_INT(f22)
+ GET_FS_INT(f23)
+ GET_FS_INT(f24)
+ GET_FS_INT(f25)
+ GET_FS_INT(f26)
+ GET_FS_INT(f27)
+ GET_FS_INT(f28)
+ GET_FS_INT(f29)
+ GET_FS_INT(f30)
+ GET_FS_INT(f31)
+
get_fs_int_done:
srl t0, t2, 31 # init the sign bit
bge t2, zero, 1f
negu t2
+ dsll t2, 33
+ dsrl t2, 33
1:
j ra
END(get_fs_int)
/*----------------------------------------------------------------------------
+ * get_fs_long --
+ *
+ * Read (long integer) the FS register (bits 15-11).
+ * This is an internal routine used by MipsEmulateFP only.
+ *
+ * Results:
+ * t0 contains the sign
+ * t2 contains the fraction
+ *
+ *----------------------------------------------------------------------------
+ */
+#define GET_FS_LONG(n) \
+ .rdata; \
+ .dword get_fs_long_/**/n; \
+ .text; \
+get_fs_long_/**/n: \
+ dmfc1 t2, $/**/n; \
+ b get_fs_long_done
+
+LEAF(get_fs_long, 0)
+ srl a3, a0, 11 - 3 # get FS field
+ and a3, a3, 0x1f << 3 # mask FS field
+ ld a3, get_fs_long_tbl(a3) # switch on register number
+ j a3
+
+ .rdata
+get_fs_long_tbl:
+ .text
+
+ GET_FS_LONG(f0)
+ GET_FS_LONG(f1)
+ GET_FS_LONG(f2)
+ GET_FS_LONG(f3)
+ GET_FS_LONG(f4)
+ GET_FS_LONG(f5)
+ GET_FS_LONG(f6)
+ GET_FS_LONG(f7)
+ GET_FS_LONG(f8)
+ GET_FS_LONG(f9)
+ GET_FS_LONG(f10)
+ GET_FS_LONG(f11)
+ GET_FS_LONG(f12)
+ GET_FS_LONG(f13)
+ GET_FS_LONG(f14)
+ GET_FS_LONG(f15)
+ GET_FS_LONG(f16)
+ GET_FS_LONG(f17)
+ GET_FS_LONG(f18)
+ GET_FS_LONG(f19)
+ GET_FS_LONG(f20)
+ GET_FS_LONG(f21)
+ GET_FS_LONG(f22)
+ GET_FS_LONG(f23)
+ GET_FS_LONG(f24)
+ GET_FS_LONG(f25)
+ GET_FS_LONG(f26)
+ GET_FS_LONG(f27)
+ GET_FS_LONG(f28)
+ GET_FS_LONG(f29)
+ GET_FS_LONG(f30)
+ GET_FS_LONG(f31)
+
+get_fs_long_done:
+ dsrl t0, t2, 63 # init the sign bit
+ bge t2, zero, 1f
+ dnegu t2
+1:
+ j ra
+END(get_fs_long)
+
+/*----------------------------------------------------------------------------
* get_ft_fs_s --
*
* Read (single precision) the FT register (bits 20-16) and
@@ -2370,79 +2025,57 @@ END(get_fs_int)
*
*----------------------------------------------------------------------------
*/
+#define GET_FT_S(n) \
+ .rdata; \
+ .dword get_ft_s_/**/n; \
+ .text; \
+get_ft_s_/**/n: \
+ mfc1 ta0, $/**/n; \
+ b get_ft_s_done
+
LEAF(get_ft_fs_s, 0)
- srl a3, a0, 17 - 2 # get FT field (even regs only)
- and a3, a3, 0xF << 2 # mask FT field
- lw a3, get_ft_s_tbl(a3) # switch on register number
+ srl a3, a0, 16 - 3 # get FT field
+ and a3, a3, 0x1f << 3 # mask FT field
+ ld a3, get_ft_s_tbl(a3) # switch on register number
j a3
.rdata
get_ft_s_tbl:
- .word get_ft_s_f0
- .word get_ft_s_f2
- .word get_ft_s_f4
- .word get_ft_s_f6
- .word get_ft_s_f8
- .word get_ft_s_f10
- .word get_ft_s_f12
- .word get_ft_s_f14
- .word get_ft_s_f16
- .word get_ft_s_f18
- .word get_ft_s_f20
- .word get_ft_s_f22
- .word get_ft_s_f24
- .word get_ft_s_f26
- .word get_ft_s_f28
- .word get_ft_s_f30
.text
-get_ft_s_f0:
- mfc1 ta0, $f0
- b get_ft_s_done
-get_ft_s_f2:
- mfc1 ta0, $f2
- b get_ft_s_done
-get_ft_s_f4:
- mfc1 ta0, $f4
- b get_ft_s_done
-get_ft_s_f6:
- mfc1 ta0, $f6
- b get_ft_s_done
-get_ft_s_f8:
- mfc1 ta0, $f8
- b get_ft_s_done
-get_ft_s_f10:
- mfc1 ta0, $f10
- b get_ft_s_done
-get_ft_s_f12:
- mfc1 ta0, $f12
- b get_ft_s_done
-get_ft_s_f14:
- mfc1 ta0, $f14
- b get_ft_s_done
-get_ft_s_f16:
- mfc1 ta0, $f16
- b get_ft_s_done
-get_ft_s_f18:
- mfc1 ta0, $f18
- b get_ft_s_done
-get_ft_s_f20:
- mfc1 ta0, $f20
- b get_ft_s_done
-get_ft_s_f22:
- mfc1 ta0, $f22
- b get_ft_s_done
-get_ft_s_f24:
- mfc1 ta0, $f24
- b get_ft_s_done
-get_ft_s_f26:
- mfc1 ta0, $f26
- b get_ft_s_done
-get_ft_s_f28:
- mfc1 ta0, $f28
- b get_ft_s_done
-get_ft_s_f30:
- mfc1 ta0, $f30
+ GET_FT_S(f0)
+ GET_FT_S(f1)
+ GET_FT_S(f2)
+ GET_FT_S(f3)
+ GET_FT_S(f4)
+ GET_FT_S(f5)
+ GET_FT_S(f6)
+ GET_FT_S(f7)
+ GET_FT_S(f8)
+ GET_FT_S(f9)
+ GET_FT_S(f10)
+ GET_FT_S(f11)
+ GET_FT_S(f12)
+ GET_FT_S(f13)
+ GET_FT_S(f14)
+ GET_FT_S(f15)
+ GET_FT_S(f16)
+ GET_FT_S(f17)
+ GET_FT_S(f18)
+ GET_FT_S(f19)
+ GET_FT_S(f20)
+ GET_FT_S(f21)
+ GET_FT_S(f22)
+ GET_FT_S(f23)
+ GET_FT_S(f24)
+ GET_FT_S(f25)
+ GET_FT_S(f26)
+ GET_FT_S(f27)
+ GET_FT_S(f28)
+ GET_FT_S(f29)
+ GET_FT_S(f30)
+ GET_FT_S(f31)
+
get_ft_s_done:
srl ta1, ta0, 23 # get exponent
and ta1, ta1, 0xFF
@@ -2468,79 +2101,57 @@ get_ft_s_done:
*
*----------------------------------------------------------------------------
*/
+#define GET_FS_S(n) \
+ .rdata; \
+ .dword get_fs_s_/**/n; \
+ .text; \
+get_fs_s_/**/n: \
+ mfc1 t0, $/**/n; \
+ b get_fs_s_done
+
ALEAF(get_fs_s)
- srl a3, a0, 12 - 2 # get FS field (even regs only)
- and a3, a3, 0xF << 2 # mask FS field
- lw a3, get_fs_s_tbl(a3) # switch on register number
+ srl a3, a0, 11 - 3 # get FS field
+ and a3, a3, 0x1f << 3 # mask FS field
+ ld a3, get_fs_s_tbl(a3) # switch on register number
j a3
.rdata
get_fs_s_tbl:
- .word get_fs_s_f0
- .word get_fs_s_f2
- .word get_fs_s_f4
- .word get_fs_s_f6
- .word get_fs_s_f8
- .word get_fs_s_f10
- .word get_fs_s_f12
- .word get_fs_s_f14
- .word get_fs_s_f16
- .word get_fs_s_f18
- .word get_fs_s_f20
- .word get_fs_s_f22
- .word get_fs_s_f24
- .word get_fs_s_f26
- .word get_fs_s_f28
- .word get_fs_s_f30
.text
-get_fs_s_f0:
- mfc1 t0, $f0
- b get_fs_s_done
-get_fs_s_f2:
- mfc1 t0, $f2
- b get_fs_s_done
-get_fs_s_f4:
- mfc1 t0, $f4
- b get_fs_s_done
-get_fs_s_f6:
- mfc1 t0, $f6
- b get_fs_s_done
-get_fs_s_f8:
- mfc1 t0, $f8
- b get_fs_s_done
-get_fs_s_f10:
- mfc1 t0, $f10
- b get_fs_s_done
-get_fs_s_f12:
- mfc1 t0, $f12
- b get_fs_s_done
-get_fs_s_f14:
- mfc1 t0, $f14
- b get_fs_s_done
-get_fs_s_f16:
- mfc1 t0, $f16
- b get_fs_s_done
-get_fs_s_f18:
- mfc1 t0, $f18
- b get_fs_s_done
-get_fs_s_f20:
- mfc1 t0, $f20
- b get_fs_s_done
-get_fs_s_f22:
- mfc1 t0, $f22
- b get_fs_s_done
-get_fs_s_f24:
- mfc1 t0, $f24
- b get_fs_s_done
-get_fs_s_f26:
- mfc1 t0, $f26
- b get_fs_s_done
-get_fs_s_f28:
- mfc1 t0, $f28
- b get_fs_s_done
-get_fs_s_f30:
- mfc1 t0, $f30
+ GET_FS_S(f0)
+ GET_FS_S(f1)
+ GET_FS_S(f2)
+ GET_FS_S(f3)
+ GET_FS_S(f4)
+ GET_FS_S(f5)
+ GET_FS_S(f6)
+ GET_FS_S(f7)
+ GET_FS_S(f8)
+ GET_FS_S(f9)
+ GET_FS_S(f10)
+ GET_FS_S(f11)
+ GET_FS_S(f12)
+ GET_FS_S(f13)
+ GET_FS_S(f14)
+ GET_FS_S(f15)
+ GET_FS_S(f16)
+ GET_FS_S(f17)
+ GET_FS_S(f18)
+ GET_FS_S(f19)
+ GET_FS_S(f20)
+ GET_FS_S(f21)
+ GET_FS_S(f22)
+ GET_FS_S(f23)
+ GET_FS_S(f24)
+ GET_FS_S(f25)
+ GET_FS_S(f26)
+ GET_FS_S(f27)
+ GET_FS_S(f28)
+ GET_FS_S(f29)
+ GET_FS_S(f30)
+ GET_FS_S(f31)
+
get_fs_s_done:
srl t1, t0, 23 # get exponent
and t1, t1, 0xFF
@@ -2564,108 +2175,69 @@ END(get_ft_fs_s)
* t0 contains the FS sign
* t1 contains the FS (biased) exponent
* t2 contains the FS fraction
- * t3 contains the FS remaining fraction
* ta0 contains the FT sign
* ta1 contains the FT (biased) exponent
* ta2 contains the FT fraction
- * ta3 contains the FT remaining fraction
*
*----------------------------------------------------------------------------
*/
+#define GET_FT_FS_D(n) \
+ .rdata; \
+ .dword get_ft_fs_d_/**/n; \
+ .text; \
+get_ft_fs_d_/**/n: \
+ dmfc1 ta2, $/**/n; \
+ b get_ft_d_done
+
LEAF(get_ft_fs_d, 0)
- srl a3, a0, 17 - 2 # get FT field (even regs only)
- and a3, a3, 0xF << 2 # mask FT field
- lw a3, get_ft_d_tbl(a3) # switch on register number
+ srl a3, a0, 16 - 3 # get FT field
+ and a3, a3, 0x1f << 3 # mask FT field
+ ld a3, get_ft_d_tbl(a3) # switch on register number
j a3
.rdata
get_ft_d_tbl:
- .word get_ft_d_f0
- .word get_ft_d_f2
- .word get_ft_d_f4
- .word get_ft_d_f6
- .word get_ft_d_f8
- .word get_ft_d_f10
- .word get_ft_d_f12
- .word get_ft_d_f14
- .word get_ft_d_f16
- .word get_ft_d_f18
- .word get_ft_d_f20
- .word get_ft_d_f22
- .word get_ft_d_f24
- .word get_ft_d_f26
- .word get_ft_d_f28
- .word get_ft_d_f30
.text
-get_ft_d_f0:
- mfc1 ta3, $f0
- mfc1 ta0, $f1
- b get_ft_d_done
-get_ft_d_f2:
- mfc1 ta3, $f2
- mfc1 ta0, $f3
- b get_ft_d_done
-get_ft_d_f4:
- mfc1 ta3, $f4
- mfc1 ta0, $f5
- b get_ft_d_done
-get_ft_d_f6:
- mfc1 ta3, $f6
- mfc1 ta0, $f7
- b get_ft_d_done
-get_ft_d_f8:
- mfc1 ta3, $f8
- mfc1 ta0, $f9
- b get_ft_d_done
-get_ft_d_f10:
- mfc1 ta3, $f10
- mfc1 ta0, $f11
- b get_ft_d_done
-get_ft_d_f12:
- mfc1 ta3, $f12
- mfc1 ta0, $f13
- b get_ft_d_done
-get_ft_d_f14:
- mfc1 ta3, $f14
- mfc1 ta0, $f15
- b get_ft_d_done
-get_ft_d_f16:
- mfc1 ta3, $f16
- mfc1 ta0, $f17
- b get_ft_d_done
-get_ft_d_f18:
- mfc1 ta3, $f18
- mfc1 ta0, $f19
- b get_ft_d_done
-get_ft_d_f20:
- mfc1 ta3, $f20
- mfc1 ta0, $f21
- b get_ft_d_done
-get_ft_d_f22:
- mfc1 ta3, $f22
- mfc1 ta0, $f23
- b get_ft_d_done
-get_ft_d_f24:
- mfc1 ta3, $f24
- mfc1 ta0, $f25
- b get_ft_d_done
-get_ft_d_f26:
- mfc1 ta3, $f26
- mfc1 ta0, $f27
- b get_ft_d_done
-get_ft_d_f28:
- mfc1 ta3, $f28
- mfc1 ta0, $f29
- b get_ft_d_done
-get_ft_d_f30:
- mfc1 ta3, $f30
- mfc1 ta0, $f31
+ GET_FT_FS_D(f0)
+ GET_FT_FS_D(f1)
+ GET_FT_FS_D(f2)
+ GET_FT_FS_D(f3)
+ GET_FT_FS_D(f4)
+ GET_FT_FS_D(f5)
+ GET_FT_FS_D(f6)
+ GET_FT_FS_D(f7)
+ GET_FT_FS_D(f8)
+ GET_FT_FS_D(f9)
+ GET_FT_FS_D(f10)
+ GET_FT_FS_D(f11)
+ GET_FT_FS_D(f12)
+ GET_FT_FS_D(f13)
+ GET_FT_FS_D(f14)
+ GET_FT_FS_D(f15)
+ GET_FT_FS_D(f16)
+ GET_FT_FS_D(f17)
+ GET_FT_FS_D(f18)
+ GET_FT_FS_D(f19)
+ GET_FT_FS_D(f20)
+ GET_FT_FS_D(f21)
+ GET_FT_FS_D(f22)
+ GET_FT_FS_D(f23)
+ GET_FT_FS_D(f24)
+ GET_FT_FS_D(f25)
+ GET_FT_FS_D(f26)
+ GET_FT_FS_D(f27)
+ GET_FT_FS_D(f28)
+ GET_FT_FS_D(f29)
+ GET_FT_FS_D(f30)
+ GET_FT_FS_D(f31)
+
get_ft_d_done:
- srl ta1, ta0, 20 # get exponent
+ dsrl ta0, ta2, 63 # get sign
+ dsrl ta1, ta2, 52 # get exponent
and ta1, ta1, 0x7FF
- and ta2, ta0, 0xFFFFF # get fraction
- srl ta0, ta0, 31 # get sign
+ dsll ta2, 12
+ dsrl ta2, 12 # get fraction
bne ta1, DEXP_INF, 1f # is it a signaling NAN?
and v0, ta2, DSIGNAL_NAN
bne v0, zero, invalid_d
@@ -2683,104 +2255,66 @@ get_ft_d_done:
* t0 contains the sign
* t1 contains the (biased) exponent
* t2 contains the fraction
- * t3 contains the remaining fraction
*
*----------------------------------------------------------------------------
*/
+#define GET_FS_D(n) \
+ .rdata; \
+ .dword get_fs_d_/**/n; \
+ .text; \
+get_fs_d_/**/n: \
+ dmfc1 t2, $/**/n; \
+ b get_fs_d_done
+
ALEAF(get_fs_d)
srl a3, a0, 12 - 2 # get FS field (even regs only)
and a3, a3, 0xF << 2 # mask FS field
- lw a3, get_fs_d_tbl(a3) # switch on register number
+ ld a3, get_fs_d_tbl(a3) # switch on register number
j a3
.rdata
get_fs_d_tbl:
- .word get_fs_d_f0
- .word get_fs_d_f2
- .word get_fs_d_f4
- .word get_fs_d_f6
- .word get_fs_d_f8
- .word get_fs_d_f10
- .word get_fs_d_f12
- .word get_fs_d_f14
- .word get_fs_d_f16
- .word get_fs_d_f18
- .word get_fs_d_f20
- .word get_fs_d_f22
- .word get_fs_d_f24
- .word get_fs_d_f26
- .word get_fs_d_f28
- .word get_fs_d_f30
.text
-get_fs_d_f0:
- mfc1 t3, $f0
- mfc1 t0, $f1
- b get_fs_d_done
-get_fs_d_f2:
- mfc1 t3, $f2
- mfc1 t0, $f3
- b get_fs_d_done
-get_fs_d_f4:
- mfc1 t3, $f4
- mfc1 t0, $f5
- b get_fs_d_done
-get_fs_d_f6:
- mfc1 t3, $f6
- mfc1 t0, $f7
- b get_fs_d_done
-get_fs_d_f8:
- mfc1 t3, $f8
- mfc1 t0, $f9
- b get_fs_d_done
-get_fs_d_f10:
- mfc1 t3, $f10
- mfc1 t0, $f11
- b get_fs_d_done
-get_fs_d_f12:
- mfc1 t3, $f12
- mfc1 t0, $f13
- b get_fs_d_done
-get_fs_d_f14:
- mfc1 t3, $f14
- mfc1 t0, $f15
- b get_fs_d_done
-get_fs_d_f16:
- mfc1 t3, $f16
- mfc1 t0, $f17
- b get_fs_d_done
-get_fs_d_f18:
- mfc1 t3, $f18
- mfc1 t0, $f19
- b get_fs_d_done
-get_fs_d_f20:
- mfc1 t3, $f20
- mfc1 t0, $f21
- b get_fs_d_done
-get_fs_d_f22:
- mfc1 t3, $f22
- mfc1 t0, $f23
- b get_fs_d_done
-get_fs_d_f24:
- mfc1 t3, $f24
- mfc1 t0, $f25
- b get_fs_d_done
-get_fs_d_f26:
- mfc1 t3, $f26
- mfc1 t0, $f27
- b get_fs_d_done
-get_fs_d_f28:
- mfc1 t3, $f28
- mfc1 t0, $f29
- b get_fs_d_done
-get_fs_d_f30:
- mfc1 t3, $f30
- mfc1 t0, $f31
+ GET_FS_D(f0)
+ GET_FS_D(f1)
+ GET_FS_D(f2)
+ GET_FS_D(f3)
+ GET_FS_D(f4)
+ GET_FS_D(f5)
+ GET_FS_D(f6)
+ GET_FS_D(f7)
+ GET_FS_D(f8)
+ GET_FS_D(f9)
+ GET_FS_D(f10)
+ GET_FS_D(f11)
+ GET_FS_D(f12)
+ GET_FS_D(f13)
+ GET_FS_D(f14)
+ GET_FS_D(f15)
+ GET_FS_D(f16)
+ GET_FS_D(f17)
+ GET_FS_D(f18)
+ GET_FS_D(f19)
+ GET_FS_D(f20)
+ GET_FS_D(f21)
+ GET_FS_D(f22)
+ GET_FS_D(f23)
+ GET_FS_D(f24)
+ GET_FS_D(f25)
+ GET_FS_D(f26)
+ GET_FS_D(f27)
+ GET_FS_D(f28)
+ GET_FS_D(f29)
+ GET_FS_D(f30)
+ GET_FS_D(f31)
+
get_fs_d_done:
- srl t1, t0, 20 # get exponent
+ dsrl t0, t2, 63 # get sign
+ dsrl t1, t2, 52 # get exponent
and t1, t1, 0x7FF
- and t2, t0, 0xFFFFF # get fraction
- srl t0, t0, 31 # get sign
+ dsll t2, 12
+ dsrl t2, 12 # get fraction
bne t1, DEXP_INF, 1f # is it a signaling NAN?
and v0, t2, DSIGNAL_NAN
bne v0, zero, invalid_d
@@ -2805,157 +2339,112 @@ END(get_ft_fs_d)
*
*----------------------------------------------------------------------------
*/
+#define CMP_FS_S(n) \
+ .rdata; \
+ .dword cmp_fs_s_/**/n; \
+ .text; \
+cmp_fs_s_/**/n: \
+ mfc1 t0, $/**/n; \
+ b cmp_fs_s_done
+
LEAF(get_cmp_s, 0)
- srl a3, a0, 12 - 2 # get FS field (even regs only)
- and a3, a3, 0xF << 2 # mask FS field
- lw a3, cmp_fs_s_tbl(a3) # switch on register number
+ srl a3, a0, 11 - 3 # get FS field
+ and a3, a3, 0x1f << 3 # mask FS field
+ ld a3, cmp_fs_s_tbl(a3) # switch on register number
j a3
.rdata
cmp_fs_s_tbl:
- .word cmp_fs_s_f0
- .word cmp_fs_s_f2
- .word cmp_fs_s_f4
- .word cmp_fs_s_f6
- .word cmp_fs_s_f8
- .word cmp_fs_s_f10
- .word cmp_fs_s_f12
- .word cmp_fs_s_f14
- .word cmp_fs_s_f16
- .word cmp_fs_s_f18
- .word cmp_fs_s_f20
- .word cmp_fs_s_f22
- .word cmp_fs_s_f24
- .word cmp_fs_s_f26
- .word cmp_fs_s_f28
- .word cmp_fs_s_f30
.text
-cmp_fs_s_f0:
- mfc1 t0, $f0
- b cmp_fs_s_done
-cmp_fs_s_f2:
- mfc1 t0, $f2
- b cmp_fs_s_done
-cmp_fs_s_f4:
- mfc1 t0, $f4
- b cmp_fs_s_done
-cmp_fs_s_f6:
- mfc1 t0, $f6
- b cmp_fs_s_done
-cmp_fs_s_f8:
- mfc1 t0, $f8
- b cmp_fs_s_done
-cmp_fs_s_f10:
- mfc1 t0, $f10
- b cmp_fs_s_done
-cmp_fs_s_f12:
- mfc1 t0, $f12
- b cmp_fs_s_done
-cmp_fs_s_f14:
- mfc1 t0, $f14
- b cmp_fs_s_done
-cmp_fs_s_f16:
- mfc1 t0, $f16
- b cmp_fs_s_done
-cmp_fs_s_f18:
- mfc1 t0, $f18
- b cmp_fs_s_done
-cmp_fs_s_f20:
- mfc1 t0, $f20
- b cmp_fs_s_done
-cmp_fs_s_f22:
- mfc1 t0, $f22
- b cmp_fs_s_done
-cmp_fs_s_f24:
- mfc1 t0, $f24
- b cmp_fs_s_done
-cmp_fs_s_f26:
- mfc1 t0, $f26
- b cmp_fs_s_done
-cmp_fs_s_f28:
- mfc1 t0, $f28
- b cmp_fs_s_done
-cmp_fs_s_f30:
- mfc1 t0, $f30
+ CMP_FS_S(f0)
+ CMP_FS_S(f1)
+ CMP_FS_S(f2)
+ CMP_FS_S(f3)
+ CMP_FS_S(f4)
+ CMP_FS_S(f5)
+ CMP_FS_S(f6)
+ CMP_FS_S(f7)
+ CMP_FS_S(f8)
+ CMP_FS_S(f9)
+ CMP_FS_S(f10)
+ CMP_FS_S(f11)
+ CMP_FS_S(f12)
+ CMP_FS_S(f13)
+ CMP_FS_S(f14)
+ CMP_FS_S(f15)
+ CMP_FS_S(f16)
+ CMP_FS_S(f17)
+ CMP_FS_S(f18)
+ CMP_FS_S(f19)
+ CMP_FS_S(f20)
+ CMP_FS_S(f21)
+ CMP_FS_S(f22)
+ CMP_FS_S(f23)
+ CMP_FS_S(f24)
+ CMP_FS_S(f25)
+ CMP_FS_S(f26)
+ CMP_FS_S(f27)
+ CMP_FS_S(f28)
+ CMP_FS_S(f29)
+ CMP_FS_S(f30)
+ CMP_FS_S(f31)
+
cmp_fs_s_done:
srl t1, t0, 23 # get exponent
and t1, t1, 0xFF
and t2, t0, 0x7FFFFF # get fraction
srl t0, t0, 31 # get sign
- srl a3, a0, 17 - 2 # get FT field (even regs only)
- and a3, a3, 0xF << 2 # mask FT field
- lw a3, cmp_ft_s_tbl(a3) # switch on register number
+#define CMP_FT_S(n) \
+ .rdata; \
+ .dword cmp_ft_s_/**/n; \
+ .text; \
+cmp_ft_s_/**/n: \
+ mfc1 ta0, $/**/n; \
+ b cmp_ft_s_done
+
+ srl a3, a0, 16 - 3 # get FT field
+ and a3, a3, 0x1f << 3 # mask FT field
+ ld a3, cmp_ft_s_tbl(a3) # switch on register number
j a3
.rdata
cmp_ft_s_tbl:
- .word cmp_ft_s_f0
- .word cmp_ft_s_f2
- .word cmp_ft_s_f4
- .word cmp_ft_s_f6
- .word cmp_ft_s_f8
- .word cmp_ft_s_f10
- .word cmp_ft_s_f12
- .word cmp_ft_s_f14
- .word cmp_ft_s_f16
- .word cmp_ft_s_f18
- .word cmp_ft_s_f20
- .word cmp_ft_s_f22
- .word cmp_ft_s_f24
- .word cmp_ft_s_f26
- .word cmp_ft_s_f28
- .word cmp_ft_s_f30
.text
-cmp_ft_s_f0:
- mfc1 ta0, $f0
- b cmp_ft_s_done
-cmp_ft_s_f2:
- mfc1 ta0, $f2
- b cmp_ft_s_done
-cmp_ft_s_f4:
- mfc1 ta0, $f4
- b cmp_ft_s_done
-cmp_ft_s_f6:
- mfc1 ta0, $f6
- b cmp_ft_s_done
-cmp_ft_s_f8:
- mfc1 ta0, $f8
- b cmp_ft_s_done
-cmp_ft_s_f10:
- mfc1 ta0, $f10
- b cmp_ft_s_done
-cmp_ft_s_f12:
- mfc1 ta0, $f12
- b cmp_ft_s_done
-cmp_ft_s_f14:
- mfc1 ta0, $f14
- b cmp_ft_s_done
-cmp_ft_s_f16:
- mfc1 ta0, $f16
- b cmp_ft_s_done
-cmp_ft_s_f18:
- mfc1 ta0, $f18
- b cmp_ft_s_done
-cmp_ft_s_f20:
- mfc1 ta0, $f20
- b cmp_ft_s_done
-cmp_ft_s_f22:
- mfc1 ta0, $f22
- b cmp_ft_s_done
-cmp_ft_s_f24:
- mfc1 ta0, $f24
- b cmp_ft_s_done
-cmp_ft_s_f26:
- mfc1 ta0, $f26
- b cmp_ft_s_done
-cmp_ft_s_f28:
- mfc1 ta0, $f28
- b cmp_ft_s_done
-cmp_ft_s_f30:
- mfc1 ta0, $f30
+ CMP_FT_S(f0)
+ CMP_FT_S(f1)
+ CMP_FT_S(f2)
+ CMP_FT_S(f3)
+ CMP_FT_S(f4)
+ CMP_FT_S(f5)
+ CMP_FT_S(f6)
+ CMP_FT_S(f7)
+ CMP_FT_S(f8)
+ CMP_FT_S(f9)
+ CMP_FT_S(f10)
+ CMP_FT_S(f11)
+ CMP_FT_S(f12)
+ CMP_FT_S(f13)
+ CMP_FT_S(f14)
+ CMP_FT_S(f15)
+ CMP_FT_S(f16)
+ CMP_FT_S(f17)
+ CMP_FT_S(f18)
+ CMP_FT_S(f19)
+ CMP_FT_S(f20)
+ CMP_FT_S(f21)
+ CMP_FT_S(f22)
+ CMP_FT_S(f23)
+ CMP_FT_S(f24)
+ CMP_FT_S(f25)
+ CMP_FT_S(f26)
+ CMP_FT_S(f27)
+ CMP_FT_S(f28)
+ CMP_FT_S(f29)
+ CMP_FT_S(f30)
+
cmp_ft_s_done:
srl ta1, ta0, 23 # get exponent
and ta1, ta1, 0xFF
@@ -2975,202 +2464,126 @@ END(get_cmp_s)
* t0 contains the sign
* t1 contains the (biased) exponent
* t2 contains the fraction
- * t3 contains the remaining fraction
* ta0 contains the sign
* ta1 contains the (biased) exponent
* ta2 contains the fraction
- * ta3 contains the remaining fraction
*
*----------------------------------------------------------------------------
*/
+#define CMP_FS_D(n) \
+ .rdata; \
+ .dword cmp_fs_d_/**/n; \
+ .text; \
+cmp_fs_d_/**/n: \
+ dmfc1 t2, $/**/n; \
+ b cmp_fs_d_done
+
LEAF(get_cmp_d, 0)
- srl a3, a0, 12 - 2 # get FS field (even regs only)
- and a3, a3, 0xF << 2 # mask FS field
- lw a3, cmp_fs_d_tbl(a3) # switch on register number
+ srl a3, a0, 11 - 3 # get FS field
+ and a3, a3, 0x1f << 3 # mask FS field
+ ld a3, cmp_fs_d_tbl(a3) # switch on register number
j a3
.rdata
cmp_fs_d_tbl:
- .word cmp_fs_d_f0
- .word cmp_fs_d_f2
- .word cmp_fs_d_f4
- .word cmp_fs_d_f6
- .word cmp_fs_d_f8
- .word cmp_fs_d_f10
- .word cmp_fs_d_f12
- .word cmp_fs_d_f14
- .word cmp_fs_d_f16
- .word cmp_fs_d_f18
- .word cmp_fs_d_f20
- .word cmp_fs_d_f22
- .word cmp_fs_d_f24
- .word cmp_fs_d_f26
- .word cmp_fs_d_f28
- .word cmp_fs_d_f30
.text
-cmp_fs_d_f0:
- mfc1 t3, $f0
- mfc1 t0, $f1
- b cmp_fs_d_done
-cmp_fs_d_f2:
- mfc1 t3, $f2
- mfc1 t0, $f3
- b cmp_fs_d_done
-cmp_fs_d_f4:
- mfc1 t3, $f4
- mfc1 t0, $f5
- b cmp_fs_d_done
-cmp_fs_d_f6:
- mfc1 t3, $f6
- mfc1 t0, $f7
- b cmp_fs_d_done
-cmp_fs_d_f8:
- mfc1 t3, $f8
- mfc1 t0, $f9
- b cmp_fs_d_done
-cmp_fs_d_f10:
- mfc1 t3, $f10
- mfc1 t0, $f11
- b cmp_fs_d_done
-cmp_fs_d_f12:
- mfc1 t3, $f12
- mfc1 t0, $f13
- b cmp_fs_d_done
-cmp_fs_d_f14:
- mfc1 t3, $f14
- mfc1 t0, $f15
- b cmp_fs_d_done
-cmp_fs_d_f16:
- mfc1 t3, $f16
- mfc1 t0, $f17
- b cmp_fs_d_done
-cmp_fs_d_f18:
- mfc1 t3, $f18
- mfc1 t0, $f19
- b cmp_fs_d_done
-cmp_fs_d_f20:
- mfc1 t3, $f20
- mfc1 t0, $f21
- b cmp_fs_d_done
-cmp_fs_d_f22:
- mfc1 t3, $f22
- mfc1 t0, $f23
- b cmp_fs_d_done
-cmp_fs_d_f24:
- mfc1 t3, $f24
- mfc1 t0, $f25
- b cmp_fs_d_done
-cmp_fs_d_f26:
- mfc1 t3, $f26
- mfc1 t0, $f27
- b cmp_fs_d_done
-cmp_fs_d_f28:
- mfc1 t3, $f28
- mfc1 t0, $f29
- b cmp_fs_d_done
-cmp_fs_d_f30:
- mfc1 t3, $f30
- mfc1 t0, $f31
+ CMP_FS_D(f0)
+ CMP_FS_D(f1)
+ CMP_FS_D(f2)
+ CMP_FS_D(f3)
+ CMP_FS_D(f4)
+ CMP_FS_D(f5)
+ CMP_FS_D(f6)
+ CMP_FS_D(f7)
+ CMP_FS_D(f8)
+ CMP_FS_D(f9)
+ CMP_FS_D(f10)
+ CMP_FS_D(f11)
+ CMP_FS_D(f12)
+ CMP_FS_D(f13)
+ CMP_FS_D(f14)
+ CMP_FS_D(f15)
+ CMP_FS_D(f16)
+ CMP_FS_D(f17)
+ CMP_FS_D(f18)
+ CMP_FS_D(f19)
+ CMP_FS_D(f20)
+ CMP_FS_D(f21)
+ CMP_FS_D(f22)
+ CMP_FS_D(f23)
+ CMP_FS_D(f24)
+ CMP_FS_D(f25)
+ CMP_FS_D(f26)
+ CMP_FS_D(f27)
+ CMP_FS_D(f28)
+ CMP_FS_D(f29)
+ CMP_FS_D(f30)
+ CMP_FS_D(f31)
+
cmp_fs_d_done:
- srl t1, t0, 20 # get exponent
+ dsrl t0, t2, 63 # get sign
+ dsrl t1, t2, 52 # get exponent
and t1, t1, 0x7FF
- and t2, t0, 0xFFFFF # get fraction
- srl t0, t0, 31 # get sign
+ dsll t2, 12
+ dsrl t2, 12 # get fraction
+
+#define CMP_FT_D(n) \
+ .rdata; \
+ .dword cmp_ft_d_/**/n; \
+ .text; \
+cmp_ft_d_/**/n: \
+ dmfc1 ta2, $/**/n; \
+ b cmp_ft_d_done
- srl a3, a0, 17 - 2 # get FT field (even regs only)
- and a3, a3, 0xF << 2 # mask FT field
- lw a3, cmp_ft_d_tbl(a3) # switch on register number
+ srl a3, a0, 16 - 3 # get FT field
+ and a3, a3, 0x1f << 3 # mask FT field
+ ld a3, cmp_ft_d_tbl(a3) # switch on register number
j a3
.rdata
cmp_ft_d_tbl:
- .word cmp_ft_d_f0
- .word cmp_ft_d_f2
- .word cmp_ft_d_f4
- .word cmp_ft_d_f6
- .word cmp_ft_d_f8
- .word cmp_ft_d_f10
- .word cmp_ft_d_f12
- .word cmp_ft_d_f14
- .word cmp_ft_d_f16
- .word cmp_ft_d_f18
- .word cmp_ft_d_f20
- .word cmp_ft_d_f22
- .word cmp_ft_d_f24
- .word cmp_ft_d_f26
- .word cmp_ft_d_f28
- .word cmp_ft_d_f30
.text
-cmp_ft_d_f0:
- mfc1 ta3, $f0
- mfc1 ta0, $f1
- b cmp_ft_d_done
-cmp_ft_d_f2:
- mfc1 ta3, $f2
- mfc1 ta0, $f3
- b cmp_ft_d_done
-cmp_ft_d_f4:
- mfc1 ta3, $f4
- mfc1 ta0, $f5
- b cmp_ft_d_done
-cmp_ft_d_f6:
- mfc1 ta3, $f6
- mfc1 ta0, $f7
- b cmp_ft_d_done
-cmp_ft_d_f8:
- mfc1 ta3, $f8
- mfc1 ta0, $f9
- b cmp_ft_d_done
-cmp_ft_d_f10:
- mfc1 ta3, $f10
- mfc1 ta0, $f11
- b cmp_ft_d_done
-cmp_ft_d_f12:
- mfc1 ta3, $f12
- mfc1 ta0, $f13
- b cmp_ft_d_done
-cmp_ft_d_f14:
- mfc1 ta3, $f14
- mfc1 ta0, $f15
- b cmp_ft_d_done
-cmp_ft_d_f16:
- mfc1 ta3, $f16
- mfc1 ta0, $f17
- b cmp_ft_d_done
-cmp_ft_d_f18:
- mfc1 ta3, $f18
- mfc1 ta0, $f19
- b cmp_ft_d_done
-cmp_ft_d_f20:
- mfc1 ta3, $f20
- mfc1 ta0, $f21
- b cmp_ft_d_done
-cmp_ft_d_f22:
- mfc1 ta3, $f22
- mfc1 ta0, $f23
- b cmp_ft_d_done
-cmp_ft_d_f24:
- mfc1 ta3, $f24
- mfc1 ta0, $f25
- b cmp_ft_d_done
-cmp_ft_d_f26:
- mfc1 ta3, $f26
- mfc1 ta0, $f27
- b cmp_ft_d_done
-cmp_ft_d_f28:
- mfc1 ta3, $f28
- mfc1 ta0, $f29
- b cmp_ft_d_done
-cmp_ft_d_f30:
- mfc1 ta3, $f30
- mfc1 ta0, $f31
+ CMP_FT_D(f0)
+ CMP_FT_D(f1)
+ CMP_FT_D(f2)
+ CMP_FT_D(f3)
+ CMP_FT_D(f4)
+ CMP_FT_D(f5)
+ CMP_FT_D(f6)
+ CMP_FT_D(f7)
+ CMP_FT_D(f8)
+ CMP_FT_D(f9)
+ CMP_FT_D(f10)
+ CMP_FT_D(f11)
+ CMP_FT_D(f12)
+ CMP_FT_D(f13)
+ CMP_FT_D(f14)
+ CMP_FT_D(f15)
+ CMP_FT_D(f16)
+ CMP_FT_D(f17)
+ CMP_FT_D(f18)
+ CMP_FT_D(f19)
+ CMP_FT_D(f20)
+ CMP_FT_D(f21)
+ CMP_FT_D(f22)
+ CMP_FT_D(f23)
+ CMP_FT_D(f24)
+ CMP_FT_D(f25)
+ CMP_FT_D(f26)
+ CMP_FT_D(f27)
+ CMP_FT_D(f28)
+ CMP_FT_D(f29)
+ CMP_FT_D(f30)
+ CMP_FT_D(f31)
+
cmp_ft_d_done:
- srl ta1, ta0, 20 # get exponent
+ dsrl ta0, ta2, 63 # get sign
+ dsrl ta1, ta2, 52 # get exponent
and ta1, ta1, 0x7FF
- and ta2, ta0, 0xFFFFF # get fraction
- srl ta0, ta0, 31 # get sign
+ dsll ta2, 12
+ dsrl ta2, 12 # get fraction
j ra
END(get_cmp_d)
@@ -3197,85 +2610,62 @@ END(get_cmp_d)
*
*----------------------------------------------------------------------------
*/
+#define SET_FD_S(n) \
+ .rdata; \
+ .dword set_fd_s_/**/n; \
+ .text; \
+set_fd_s_/**/n: \
+ mtc1 t2, $/**/n; \
+ j ra
+
LEAF(set_fd_s, 0)
sll t0, t0, 31 # position sign
sll t1, t1, 23 # position exponent
or t2, t2, t0
or t2, t2, t1
ALEAF(set_fd_word)
- srl a3, a0, 7 - 2 # get FD field (even regs only)
- and a3, a3, 0xF << 2 # mask FT field
- lw a3, set_fd_s_tbl(a3) # switch on register number
+ srl a3, a0, 6 - 3 # get FD field
+ and a3, a3, 0x1f << 3 # mask FT field
+ ld a3, set_fd_s_tbl(a3) # switch on register number
j a3
.rdata
set_fd_s_tbl:
- .word set_fd_s_f0
- .word set_fd_s_f2
- .word set_fd_s_f4
- .word set_fd_s_f6
- .word set_fd_s_f8
- .word set_fd_s_f10
- .word set_fd_s_f12
- .word set_fd_s_f14
- .word set_fd_s_f16
- .word set_fd_s_f18
- .word set_fd_s_f20
- .word set_fd_s_f22
- .word set_fd_s_f24
- .word set_fd_s_f26
- .word set_fd_s_f28
- .word set_fd_s_f30
.text
-set_fd_s_f0:
- mtc1 t2, $f0
- j ra
-set_fd_s_f2:
- mtc1 t2, $f2
- j ra
-set_fd_s_f4:
- mtc1 t2, $f4
- j ra
-set_fd_s_f6:
- mtc1 t2, $f6
- j ra
-set_fd_s_f8:
- mtc1 t2, $f8
- j ra
-set_fd_s_f10:
- mtc1 t2, $f10
- j ra
-set_fd_s_f12:
- mtc1 t2, $f12
- j ra
-set_fd_s_f14:
- mtc1 t2, $f14
- j ra
-set_fd_s_f16:
- mtc1 t2, $f16
- j ra
-set_fd_s_f18:
- mtc1 t2, $f18
- j ra
-set_fd_s_f20:
- mtc1 t2, $f20
- j ra
-set_fd_s_f22:
- mtc1 t2, $f22
- j ra
-set_fd_s_f24:
- mtc1 t2, $f24
- j ra
-set_fd_s_f26:
- mtc1 t2, $f26
- j ra
-set_fd_s_f28:
- mtc1 t2, $f28
- j ra
-set_fd_s_f30:
- mtc1 t2, $f30
- j ra
+ SET_FD_S(f0)
+ SET_FD_S(f1)
+ SET_FD_S(f2)
+ SET_FD_S(f3)
+ SET_FD_S(f4)
+ SET_FD_S(f5)
+ SET_FD_S(f6)
+ SET_FD_S(f7)
+ SET_FD_S(f8)
+ SET_FD_S(f9)
+ SET_FD_S(f10)
+ SET_FD_S(f11)
+ SET_FD_S(f12)
+ SET_FD_S(f13)
+ SET_FD_S(f14)
+ SET_FD_S(f15)
+ SET_FD_S(f16)
+ SET_FD_S(f17)
+ SET_FD_S(f18)
+ SET_FD_S(f19)
+ SET_FD_S(f20)
+ SET_FD_S(f21)
+ SET_FD_S(f22)
+ SET_FD_S(f23)
+ SET_FD_S(f24)
+ SET_FD_S(f25)
+ SET_FD_S(f26)
+ SET_FD_S(f27)
+ SET_FD_S(f28)
+ SET_FD_S(f29)
+ SET_FD_S(f30)
+ SET_FD_S(f31)
+
END(set_fd_s)
/*----------------------------------------------------------------------------
@@ -3289,104 +2679,64 @@ END(set_fd_s)
* t0 contains the sign
* t1 contains the (biased) exponent
* t2 contains the fraction
- * t3 contains the remaining fraction
*
*----------------------------------------------------------------------------
*/
+#define SET_FD_D(n) \
+ .rdata; \
+ .dword set_fd_d_/**/n; \
+ .text; \
+set_fd_d_/**/n: \
+ dmtc1 t0, $/**/n; \
+ j ra
+
LEAF(set_fd_d, 0)
- sll t0, t0, 31 # set sign
- sll t1, t1, 20 # set exponent
+ dsll t0, 63 # set sign
+ dsll t1, t1, 52 # set exponent
or t0, t0, t1
or t0, t0, t2 # set fraction
- srl a3, a0, 7 - 2 # get FD field (even regs only)
- and a3, a3, 0xF << 2 # mask FD field
- lw a3, set_fd_d_tbl(a3) # switch on register number
+ srl a3, a0, 6 - 3 # get FD field
+ and a3, a3, 0x1f << 3 # mask FD field
+ ld a3, set_fd_d_tbl(a3) # switch on register number
j a3
.rdata
set_fd_d_tbl:
- .word set_fd_d_f0
- .word set_fd_d_f2
- .word set_fd_d_f4
- .word set_fd_d_f6
- .word set_fd_d_f8
- .word set_fd_d_f10
- .word set_fd_d_f12
- .word set_fd_d_f14
- .word set_fd_d_f16
- .word set_fd_d_f18
- .word set_fd_d_f20
- .word set_fd_d_f22
- .word set_fd_d_f24
- .word set_fd_d_f26
- .word set_fd_d_f28
- .word set_fd_d_f30
.text
-set_fd_d_f0:
- mtc1 t3, $f0
- mtc1 t0, $f1
- j ra
-set_fd_d_f2:
- mtc1 t3, $f2
- mtc1 t0, $f3
- j ra
-set_fd_d_f4:
- mtc1 t3, $f4
- mtc1 t0, $f5
- j ra
-set_fd_d_f6:
- mtc1 t3, $f6
- mtc1 t0, $f7
- j ra
-set_fd_d_f8:
- mtc1 t3, $f8
- mtc1 t0, $f9
- j ra
-set_fd_d_f10:
- mtc1 t3, $f10
- mtc1 t0, $f11
- j ra
-set_fd_d_f12:
- mtc1 t3, $f12
- mtc1 t0, $f13
- j ra
-set_fd_d_f14:
- mtc1 t3, $f14
- mtc1 t0, $f15
- j ra
-set_fd_d_f16:
- mtc1 t3, $f16
- mtc1 t0, $f17
- j ra
-set_fd_d_f18:
- mtc1 t3, $f18
- mtc1 t0, $f19
- j ra
-set_fd_d_f20:
- mtc1 t3, $f20
- mtc1 t0, $f21
- j ra
-set_fd_d_f22:
- mtc1 t3, $f22
- mtc1 t0, $f23
- j ra
-set_fd_d_f24:
- mtc1 t3, $f24
- mtc1 t0, $f25
- j ra
-set_fd_d_f26:
- mtc1 t3, $f26
- mtc1 t0, $f27
- j ra
-set_fd_d_f28:
- mtc1 t3, $f28
- mtc1 t0, $f29
- j ra
-set_fd_d_f30:
- mtc1 t3, $f30
- mtc1 t0, $f31
- j ra
+ SET_FD_D(f0)
+ SET_FD_D(f1)
+ SET_FD_D(f2)
+ SET_FD_D(f3)
+ SET_FD_D(f4)
+ SET_FD_D(f5)
+ SET_FD_D(f6)
+ SET_FD_D(f7)
+ SET_FD_D(f8)
+ SET_FD_D(f9)
+ SET_FD_D(f10)
+ SET_FD_D(f11)
+ SET_FD_D(f12)
+ SET_FD_D(f13)
+ SET_FD_D(f14)
+ SET_FD_D(f15)
+ SET_FD_D(f16)
+ SET_FD_D(f17)
+ SET_FD_D(f18)
+ SET_FD_D(f19)
+ SET_FD_D(f20)
+ SET_FD_D(f21)
+ SET_FD_D(f22)
+ SET_FD_D(f23)
+ SET_FD_D(f24)
+ SET_FD_D(f25)
+ SET_FD_D(f26)
+ SET_FD_D(f27)
+ SET_FD_D(f28)
+ SET_FD_D(f29)
+ SET_FD_D(f30)
+ SET_FD_D(f31)
+
END(set_fd_d)
/*----------------------------------------------------------------------------
@@ -3443,62 +2793,52 @@ END(renorm_fs_s)
*
* Results:
* t1 unbiased exponent
- * t2,t3 normalized fraction
+ * t2 normalized fraction
*
*----------------------------------------------------------------------------
*/
LEAF(renorm_fs_d, 0)
/*
- * Find out how many leading zero bits are in t2,t3 and put in t9.
+ * Find out how many leading zero bits are in t2 and put in t9.
*/
move v0, t2
move t9, zero
- bne t2, zero, 1f
- move v0, t3
+ dsrl v1, v0, 32
+ bne v1, zero, 1f
addu t9, 32
+ dsll v0, 32
1:
- srl v1, v0, 16
+ dsrl v1, v0, 16
bne v1, zero, 1f
addu t9, 16
- sll v0, 16
+ dsll v0, 16
1:
- srl v1, v0, 24
+ dsrl v1, v0, 24
bne v1, zero, 1f
addu t9, 8
- sll v0, 8
+ dsll v0, 8
1:
- srl v1, v0, 28
+ dsrl v1, v0, 28
bne v1, zero, 1f
addu t9, 4
- sll v0, 4
+ dsll v0, 4
1:
- srl v1, v0, 30
+ dsrl v1, v0, 30
bne v1, zero, 1f
addu t9, 2
- sll v0, 2
+ dsll v0, 2
1:
- srl v1, v0, 31
+ dsrl v1, v0, 31
bne v1, zero, 1f
addu t9, 1
/*
- * Now shift t2,t3 the correct number of bits.
+ * Now shift t2 the correct number of bits.
*/
1:
subu t9, t9, DLEAD_ZEROS # dont count normal leading zeros
li t1, DEXP_MIN
- subu t1, t1, t9 # adjust exponent
- li v0, 32
- blt t9, v0, 1f
- subu t9, t9, v0 # shift fraction left >= 32 bits
- sll t2, t3, t9
- move t3, zero
- j ra
-1:
- subu v0, v0, t9 # shift fraction left < 32 bits
- sll t2, t2, t9
- srl v1, t3, v0
- or t2, t2, v1
- sll t3, t3, t9
+ subu t1, t9 # adjust exponent
+ dsll t2, t9
j ra
END(renorm_fs_d)
@@ -3546,8 +2886,8 @@ LEAF(renorm_ft_s, 0)
1:
subu t9, t9, SLEAD_ZEROS # dont count normal leading zeros
li ta1, SEXP_MIN
- subu ta1, ta1, t9 # adjust exponent
- sll ta2, ta2, t9
+ subu ta1, t9 # adjust exponent
+ sll ta2, t9
j ra
END(renorm_ft_s)
@@ -3556,61 +2896,51 @@ END(renorm_ft_s)
*
* Results:
* ta1 unbiased exponent
- * ta2,ta3 normalized fraction
+ * ta2 normalized fraction
*
*----------------------------------------------------------------------------
*/
LEAF(renorm_ft_d, 0)
/*
- * Find out how many leading zero bits are in ta2,ta3 and put in t9.
+ * Find out how many leading zero bits are in ta2 and put in t9.
*/
move v0, ta2
move t9, zero
- bne ta2, zero, 1f
- move v0, ta3
+ dsrl v1, v0, 32
+ bne v1, zero, 1f
addu t9, 32
+ dsll v0, 32
1:
- srl v1, v0, 16
+ dsrl v1, v0, 16
bne v1, zero, 1f
addu t9, 16
- sll v0, 16
+ dsll v0, 16
1:
- srl v1, v0, 24
+ dsrl v1, v0, 24
bne v1, zero, 1f
addu t9, 8
- sll v0, 8
+ dsll v0, 8
1:
- srl v1, v0, 28
+ dsrl v1, v0, 28
bne v1, zero, 1f
addu t9, 4
- sll v0, 4
+ dsll v0, 4
1:
- srl v1, v0, 30
+ dsrl v1, v0, 30
bne v1, zero, 1f
addu t9, 2
- sll v0, 2
+ dsll v0, 2
1:
- srl v1, v0, 31
+ dsrl v1, v0, 31
bne v1, zero, 1f
addu t9, 1
/*
- * Now shift ta2,ta3 the correct number of bits.
+ * Now shift ta2 the correct number of bits.
*/
1:
subu t9, t9, DLEAD_ZEROS # dont count normal leading zeros
li ta1, DEXP_MIN
- subu ta1, ta1, t9 # adjust exponent
- li v0, 32
- blt t9, v0, 1f
- subu t9, t9, v0 # shift fraction left >= 32 bits
- sll ta2, ta3, t9
- move ta3, zero
- j ra
-1:
- subu v0, v0, t9 # shift fraction left < 32 bits
- sll ta2, ta2, t9
- srl v1, ta3, v0
- or ta2, ta2, v1
- sll ta3, ta3, t9
+ subu ta1, t9 # adjust exponent
+ dsll ta2, t9
j ra
END(renorm_ft_d)
diff --git a/sys/arch/mips64/mips64/lcore_float.S b/sys/arch/mips64/mips64/lcore_float.S
index e6975130293..eea9353d8dd 100644
--- a/sys/arch/mips64/mips64/lcore_float.S
+++ b/sys/arch/mips64/mips64/lcore_float.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: lcore_float.S,v 1.8 2004/10/20 12:49:15 pefo Exp $ */
+/* $OpenBSD: lcore_float.S,v 1.9 2004/10/30 14:48:59 pefo Exp $ */
/*
* Copyright (c) 2001-2003 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -430,18 +430,20 @@ NON_LEAF(MipsFPTrap, FRAMESZ(CF_SZ), ra)
PTR_S ra, CF_RA_OFFS(sp)
.mask 0x80000000, (CF_RA_OFFS - FRAMESZ(CF_SZ))
+ PTR_S a2, 2*REGSZ(sp)
+ PTR_S a3, 3*REGSZ(sp)
or t1, t0, SR_COP_1_BIT
mtc0 t1, COP_0_STATUS_REG
ITLBNOPFIX
- cfc1 t1, FPC_CSR # stall til FP done
- cfc1 t1, FPC_CSR # now get status
+ cfc1 t1, FPC_CSR # stall til FP done
+ cfc1 t1, FPC_CSR # now get status
nop
- sll t2, t1, (31 - 17) # unimplemented operation?
+ sll t2, t1, (31-17) # unimplemented operation?
bgez t2, 3f # no, normal trap
nop
/*
- * We got an unimplemented operation trap so
- * fetch the instruction, compute the next PC and emulate the instruction.
+ * We got an unimplemented operation trap so fetch the instruction,
+ * compute the next PC and emulate the instruction.
*/
bgez a1, 1f # Check the branch delay bit.
nop
@@ -449,42 +451,56 @@ NON_LEAF(MipsFPTrap, FRAMESZ(CF_SZ), ra)
* The instruction is in the branch delay slot so the branch will have to
* be emulated to get the resulting PC.
*/
- PTR_S a2, FRAMESZ(CF_SZ) + 2 * REGSZ(sp)
- PTR_L a0, curprocpaddr # first arg is ptr to CPU regs
- move a1, a2 # second arg is instruction PC
- move a2, t1 # third arg is floating point CSR
- jal MipsEmulateBranch # compute PC after branch
- move a3, zero # fourth arg is FALSE
+ PTR_L a0, curprocpaddr # first arg is ptr to CPU regs
+ move a1, a2 # second arg is instruction PC
+ move a2, t1 # third arg is the FP CSR
+ jal MipsEmulateBranch # compute PC after branch
+ move a3, zero # fourth arg is FALSE
/*
* Now load the floating-point instruction in the branch delay slot
* to be emulated.
*/
- PTR_L a2, FRAMESZ(CF_SZ) + 2 * REGSZ(sp) # restore EXC pc
+ PTR_L a2, 2*REGSZ(sp) # restore EXC pc
b 2f
- lw a0, 4(a2) # a0 = coproc instruction
+ lw a0, 4(a2) # a0 = coproc instruction
/*
* This is not in the branch delay slot so calculate the resulting
* PC (epc + 4) into v0 and continue to MipsEmulateFP().
*/
1:
- lw a0, 0(a2) # a0 = coproc instruction
- PTR_ADDU v0, a2, 4 # v0 = next pc
+ lw a0, 0(a2) # a0 = coproc instruction
+ PTR_ADDU v0, a2, 4 # v0 = next pc
2:
- PTR_L a3, curprocpaddr # first arg is ptr to CPU regs
+ PTR_L a3, curprocpaddr # first arg is ptr to CPU regs
PTR_S v0, U_PCB_REGS+(PC * REGSZ)(a3) # save new pc
/*
* Check to see if the instruction to be emulated is a floating-point
* instruction.
*/
srl a3, a0, OPCODE_SHIFT
- beq a3, OPCODE_C1, 4f # this should never fail
+ beq a3, OPCODE_C1, 5f # this should never fail
nop
/*
* Send a floating point exception signal to the current process.
*/
3:
- PTR_L a0, curproc # get current process
cfc1 a2, FPC_CSR # code = FP execptions
+ PTR_L a0, curproc # get current process
+ PTR_L a4, 3*REGSZ(sp)
+ and v0, a2, FPC_EXCEPTION_INEXACT
+ bnez v0, 4f
+ li a3, 6
+ and v0, a2, FPC_EXCEPTION_UNDERFLOW
+ bnez v0, 4f
+ li a3, 5
+ and v0, a2, FPC_EXCEPTION_OVERFLOW
+ bnez v0, 4f
+ li a3, 4
+ and v0, a2, FPC_EXCEPTION_DIV0
+ bnez v0, 4f
+ li a3, 3
+ li a3, 7 # XXX FPE_FLTINV
+4:
ctc1 zero, FPC_CSR # Clear exceptions
jal trapsignal
li a1, SIGFPE
@@ -494,7 +510,7 @@ NON_LEAF(MipsFPTrap, FRAMESZ(CF_SZ), ra)
/*
* Finally, we can call MipsEmulateFP() where a0 is the instruction to emulate.
*/
-4:
+5:
jal MipsEmulateFP
nop
diff --git a/sys/arch/mips64/mips64/trap.c b/sys/arch/mips64/mips64/trap.c
index 9fd8a96f493..b688a405fd5 100644
--- a/sys/arch/mips64/mips64/trap.c
+++ b/sys/arch/mips64/mips64/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.14 2004/10/20 12:49:15 pefo Exp $ */
+/* $OpenBSD: trap.c,v 1.15 2004/10/30 14:48:59 pefo Exp $ */
/* tracked to 1.23 */
/*
@@ -146,7 +146,7 @@ int kdb_trap(int, db_regs_t *);
extern u_long intrcnt[];
extern void MipsSwitchFPState(struct proc *, struct trap_frame *);
extern void MipsSwitchFPState16(struct proc *, struct trap_frame *);
-extern void MipsFPTrap(u_int, u_int, u_int);
+extern void MipsFPTrap(u_int, u_int, u_int, union sigval);
register_t trap(struct trap_frame *);
int cpu_singlestep(struct proc *);
@@ -740,7 +740,9 @@ printf("SIG-BUSB @%p pc %p, ra %p\n", trapframe->badvaddr, trapframe->pc, trapfr
goto err;
case T_FPE+T_USER:
- MipsFPTrap(trapframe->sr, trapframe->cause, trapframe->pc);
+printf("FPU Trap, pc=%p instr=0x%08x\n", trapframe->pc, *(int *)trapframe->pc);
+ sv.sival_ptr = (void *)trapframe->pc;
+ MipsFPTrap(trapframe->sr, trapframe->cause, trapframe->pc, sv);
goto out;
case T_OVFLOW+T_USER:
@@ -774,7 +776,7 @@ printf("SIG-BUSB @%p pc %p, ra %p\n", trapframe->badvaddr, trapframe->pc, trapfr
p->p_md.md_regs->pc = trapframe->pc;
p->p_md.md_regs->cause = trapframe->cause;
p->p_md.md_regs->badvaddr = trapframe->badvaddr;
- sv.sival_int = trapframe->badvaddr;
+ sv.sival_ptr = (void *)trapframe->badvaddr;
trapsignal(p, i, ucode, typ, sv);
out:
/*