diff options
author | Per Fogelstrom <pefo@cvs.openbsd.org> | 2004-10-30 14:49:00 +0000 |
---|---|---|
committer | Per Fogelstrom <pefo@cvs.openbsd.org> | 2004-10-30 14:49:00 +0000 |
commit | aac36bb83dfc61652e4d8ba38c6190b2bb760f7d (patch) | |
tree | 5b7de0ffc4c172e0e317fb899391a04275ce7f70 /sys/arch/mips64 | |
parent | 6e175411c627e94b02c1c7ecb6797a74910513f8 (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.c | 18 | ||||
-rw-r--r-- | sys/arch/mips64/mips64/disksubr.c | 14 | ||||
-rw-r--r-- | sys/arch/mips64/mips64/fp.S | 2848 | ||||
-rw-r--r-- | sys/arch/mips64/mips64/lcore_float.S | 56 | ||||
-rw-r--r-- | sys/arch/mips64/mips64/trap.c | 10 |
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: /* |