1*0a6a1f1dSLionel Sambuc/* $NetBSD: ldexp.S,v 1.10 2014/09/17 11:01:05 joerg Exp $ */ 22fe8fb19SBen Gras 32fe8fb19SBen Gras/*- 42fe8fb19SBen Gras * Copyright (c) 1991, 1993 52fe8fb19SBen Gras * The Regents of the University of California. All rights reserved. 62fe8fb19SBen Gras * 72fe8fb19SBen Gras * This code is derived from software contributed to Berkeley by 82fe8fb19SBen Gras * Ralph Campbell. 92fe8fb19SBen Gras * 102fe8fb19SBen Gras * Redistribution and use in source and binary forms, with or without 112fe8fb19SBen Gras * modification, are permitted provided that the following conditions 122fe8fb19SBen Gras * are met: 132fe8fb19SBen Gras * 1. Redistributions of source code must retain the above copyright 142fe8fb19SBen Gras * notice, this list of conditions and the following disclaimer. 152fe8fb19SBen Gras * 2. Redistributions in binary form must reproduce the above copyright 162fe8fb19SBen Gras * notice, this list of conditions and the following disclaimer in the 172fe8fb19SBen Gras * documentation and/or other materials provided with the distribution. 182fe8fb19SBen Gras * 3. Neither the name of the University nor the names of its contributors 192fe8fb19SBen Gras * may be used to endorse or promote products derived from this software 202fe8fb19SBen Gras * without specific prior written permission. 212fe8fb19SBen Gras * 222fe8fb19SBen Gras * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 232fe8fb19SBen Gras * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 242fe8fb19SBen Gras * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 252fe8fb19SBen Gras * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 262fe8fb19SBen Gras * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 272fe8fb19SBen Gras * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 282fe8fb19SBen Gras * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 292fe8fb19SBen Gras * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 302fe8fb19SBen Gras * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 312fe8fb19SBen Gras * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 322fe8fb19SBen Gras * SUCH DAMAGE. 332fe8fb19SBen Gras */ 342fe8fb19SBen Gras 352fe8fb19SBen Gras#include <mips/asm.h> 362fe8fb19SBen Gras 372fe8fb19SBen Gras#if defined(LIBC_SCCS) && !defined(lint) 382fe8fb19SBen Gras#if 0 392fe8fb19SBen Gras RCSID("from: @(#)ldexp.s 8.1 (Berkeley) 6/4/93") 402fe8fb19SBen Gras#else 41*0a6a1f1dSLionel Sambuc RCSID("$NetBSD: ldexp.S,v 1.10 2014/09/17 11:01:05 joerg Exp $") 422fe8fb19SBen Gras#endif 432fe8fb19SBen Gras#endif /* LIBC_SCCS and not lint */ 442fe8fb19SBen Gras 452fe8fb19SBen Gras#define DEXP_INF 0x7ff 462fe8fb19SBen Gras#define DEXP_BIAS 1023 472fe8fb19SBen Gras#define DEXP_MIN -1022 482fe8fb19SBen Gras#define DEXP_MAX 1023 492fe8fb19SBen Gras#define DFRAC_BITS 52 502fe8fb19SBen Gras#define DIMPL_ONE 0x00100000 512fe8fb19SBen Gras#define DLEAD_ZEROS 31 - 20 522fe8fb19SBen Gras#define STICKYBIT 1 532fe8fb19SBen Gras#define GUARDBIT 0x80000000 542fe8fb19SBen Gras#define DSIGNAL_NAN 0x00040000 552fe8fb19SBen Gras#define DQUIET_NAN0 0x0007ffff 562fe8fb19SBen Gras#define DQUIET_NAN1 0xffffffff 572fe8fb19SBen Gras 582fe8fb19SBen Gras/* 592fe8fb19SBen Gras * double ldexp(x, N) 602fe8fb19SBen Gras * double x; int N; 612fe8fb19SBen Gras * 622fe8fb19SBen Gras * Return x * (2**N), for integer values N. 632fe8fb19SBen Gras */ 642fe8fb19SBen GrasLEAF(ldexp) 652fe8fb19SBen Gras mfc1 v1, $f13 # get MSW of x 662fe8fb19SBen Gras mfc1 t3, $f12 # get LSW of x 672fe8fb19SBen Gras sll t1, v1, 1 # get x exponent 682fe8fb19SBen Gras srl t1, t1, 32 - 11 692fe8fb19SBen Gras beq t1, DEXP_INF, 9f # is it a NAN or infinity? 702fe8fb19SBen Gras beq t1, zero, 1f # zero or denormalized number? 712fe8fb19SBen Gras addu t1, t1, a2 # scale exponent 722fe8fb19SBen Gras sll v0, a2, 20 # position N for addition 732fe8fb19SBen Gras bge t1, DEXP_INF, 8f # overflow? 742fe8fb19SBen Gras addu v0, v0, v1 # multiply by (2**N) 752fe8fb19SBen Gras ble t1, zero, 4f # underflow? 762fe8fb19SBen Gras mtc1 v0, $f1 # save MSW of result 772fe8fb19SBen Gras mtc1 t3, $f0 # save LSW of result 782fe8fb19SBen Gras j ra 792fe8fb19SBen Gras1: 802fe8fb19SBen Gras sll t2, v1, 32 - 20 # get x fraction 812fe8fb19SBen Gras srl t2, t2, 32 - 20 822fe8fb19SBen Gras srl t0, v1, 31 # get x sign 832fe8fb19SBen Gras bne t2, zero, 1f 842fe8fb19SBen Gras beq t3, zero, 9f # result is zero 852fe8fb19SBen Gras1: 862fe8fb19SBen Gras/* 872fe8fb19SBen Gras * Find out how many leading zero bits are in t2,t3 and put in t9. 882fe8fb19SBen Gras */ 892fe8fb19SBen Gras move v0, t2 902fe8fb19SBen Gras move t9, zero 912fe8fb19SBen Gras bne t2, zero, 1f 922fe8fb19SBen Gras move v0, t3 932fe8fb19SBen Gras addu t9, 32 942fe8fb19SBen Gras1: 952fe8fb19SBen Gras srl ta0, v0, 16 962fe8fb19SBen Gras bne ta0, zero, 1f 972fe8fb19SBen Gras addu t9, 16 982fe8fb19SBen Gras sll v0, 16 992fe8fb19SBen Gras1: 1002fe8fb19SBen Gras srl ta0, v0, 24 1012fe8fb19SBen Gras bne ta0, zero, 1f 1022fe8fb19SBen Gras addu t9, 8 1032fe8fb19SBen Gras sll v0, 8 1042fe8fb19SBen Gras1: 1052fe8fb19SBen Gras srl ta0, v0, 28 1062fe8fb19SBen Gras bne ta0, zero, 1f 1072fe8fb19SBen Gras addu t9, 4 1082fe8fb19SBen Gras sll v0, 4 1092fe8fb19SBen Gras1: 1102fe8fb19SBen Gras srl ta0, v0, 30 1112fe8fb19SBen Gras bne ta0, zero, 1f 1122fe8fb19SBen Gras addu t9, 2 1132fe8fb19SBen Gras sll v0, 2 1142fe8fb19SBen Gras1: 1152fe8fb19SBen Gras srl ta0, v0, 31 1162fe8fb19SBen Gras bne ta0, zero, 1f 1172fe8fb19SBen Gras addu t9, 1 1182fe8fb19SBen Gras/* 1192fe8fb19SBen Gras * Now shift t2,t3 the correct number of bits. 1202fe8fb19SBen Gras */ 1212fe8fb19SBen Gras1: 1222fe8fb19SBen Gras subu t9, t9, DLEAD_ZEROS # dont count normal leading zeros 1232fe8fb19SBen Gras li t1, DEXP_MIN + DEXP_BIAS 1242fe8fb19SBen Gras subu t1, t1, t9 # adjust exponent 1252fe8fb19SBen Gras addu t1, t1, a2 # scale exponent 1262fe8fb19SBen Gras li v0, 32 1272fe8fb19SBen Gras blt t9, v0, 1f 1282fe8fb19SBen Gras subu t9, t9, v0 # shift fraction left >= 32 bits 1292fe8fb19SBen Gras sll t2, t3, t9 1302fe8fb19SBen Gras move t3, zero 1312fe8fb19SBen Gras b 2f 1322fe8fb19SBen Gras1: 1332fe8fb19SBen Gras subu v0, v0, t9 # shift fraction left < 32 bits 1342fe8fb19SBen Gras sll t2, t2, t9 1352fe8fb19SBen Gras srl ta0, t3, v0 1362fe8fb19SBen Gras or t2, t2, ta0 1372fe8fb19SBen Gras sll t3, t3, t9 1382fe8fb19SBen Gras2: 1392fe8fb19SBen Gras bge t1, DEXP_INF, 8f # overflow? 1402fe8fb19SBen Gras ble t1, zero, 4f # underflow? 1412fe8fb19SBen Gras sll t2, t2, 32 - 20 # clear implied one bit 1422fe8fb19SBen Gras srl t2, t2, 32 - 20 1432fe8fb19SBen Gras3: 1442fe8fb19SBen Gras sll t1, t1, 31 - 11 # reposition exponent 1452fe8fb19SBen Gras sll t0, t0, 31 # reposition sign 1462fe8fb19SBen Gras or t0, t0, t1 # put result back together 1472fe8fb19SBen Gras or t0, t0, t2 1482fe8fb19SBen Gras mtc1 t0, $f1 # save MSW of result 1492fe8fb19SBen Gras mtc1 t3, $f0 # save LSW of result 1502fe8fb19SBen Gras j ra 1512fe8fb19SBen Gras4: 1522fe8fb19SBen Gras li v0, 0x80000000 1532fe8fb19SBen Gras ble t1, -52, 7f # is result too small for denorm? 1542fe8fb19SBen Gras sll t2, v1, 31 - 20 # clear exponent, extract fraction 1552fe8fb19SBen Gras or t2, t2, v0 # set implied one bit 1562fe8fb19SBen Gras blt t1, -30, 2f # will all bits in t3 be shifted out? 1572fe8fb19SBen Gras srl t2, t2, 31 - 20 # shift fraction back to normal position 1582fe8fb19SBen Gras subu t1, t1, 1 1592fe8fb19SBen Gras sll ta0, t2, t1 # shift right t2,t3 based on exponent 1602fe8fb19SBen Gras srl t8, t3, t1 # save bits shifted out 1612fe8fb19SBen Gras negu t1 1622fe8fb19SBen Gras srl t3, t3, t1 1632fe8fb19SBen Gras or t3, t3, ta0 1642fe8fb19SBen Gras srl t2, t2, t1 1652fe8fb19SBen Gras bge t8, zero, 1f # does result need to be rounded? 1662fe8fb19SBen Gras addu t3, t3, 1 # round result 1672fe8fb19SBen Gras sltu ta0, t3, 1 1682fe8fb19SBen Gras sll t8, t8, 1 1692fe8fb19SBen Gras addu t2, t2, ta0 1702fe8fb19SBen Gras bne t8, zero, 1f # round result to nearest 1712fe8fb19SBen Gras and t3, t3, ~1 1722fe8fb19SBen Gras1: 1732fe8fb19SBen Gras mtc1 t3, $f0 # save denormalized result (LSW) 1742fe8fb19SBen Gras mtc1 t2, $f1 # save denormalized result (MSW) 1752fe8fb19SBen Gras bge v1, zero, 1f # should result be negative? 1762fe8fb19SBen Gras neg.d $f0, $f0 # negate result 1772fe8fb19SBen Gras1: 1782fe8fb19SBen Gras j ra 1792fe8fb19SBen Gras2: 1802fe8fb19SBen Gras mtc1 zero, $f1 # exponent and upper fraction 1812fe8fb19SBen Gras addu t1, t1, 20 # compute amount to shift right by 1822fe8fb19SBen Gras sll t8, t2, t1 # save bits shifted out 1832fe8fb19SBen Gras negu t1 1842fe8fb19SBen Gras srl t3, t2, t1 1852fe8fb19SBen Gras bge t8, zero, 1f # does result need to be rounded? 1862fe8fb19SBen Gras addu t3, t3, 1 # round result 1872fe8fb19SBen Gras sltu ta0, t3, 1 1882fe8fb19SBen Gras sll t8, t8, 1 1892fe8fb19SBen Gras mtc1 ta0, $f1 # exponent and upper fraction 1902fe8fb19SBen Gras bne t8, zero, 1f # round result to nearest 1912fe8fb19SBen Gras and t3, t3, ~1 1922fe8fb19SBen Gras1: 1932fe8fb19SBen Gras mtc1 t3, $f0 1942fe8fb19SBen Gras bge v1, zero, 1f # is result negative? 1952fe8fb19SBen Gras neg.d $f0, $f0 # negate result 1962fe8fb19SBen Gras1: 1972fe8fb19SBen Gras j ra 1982fe8fb19SBen Gras7: 1992fe8fb19SBen Gras mtc1 zero, $f0 # result is zero 2002fe8fb19SBen Gras mtc1 zero, $f1 2012fe8fb19SBen Gras beq t0, zero, 1f # is result positive? 2022fe8fb19SBen Gras neg.d $f0, $f0 # negate result 2032fe8fb19SBen Gras1: 2042fe8fb19SBen Gras j ra 2052fe8fb19SBen Gras8: 2062fe8fb19SBen Gras li t1, 0x7ff00000 # result is infinity (MSW) 2072fe8fb19SBen Gras mtc1 t1, $f1 2082fe8fb19SBen Gras mtc1 zero, $f0 # result is infinity (LSW) 2092fe8fb19SBen Gras bge v1, zero, 1f # should result be negative infinity? 2102fe8fb19SBen Gras neg.d $f0, $f0 # result is negative infinity 2112fe8fb19SBen Gras1: 212*0a6a1f1dSLionel Sambuc add.d $f0, $f0, $f0 # cause overflow faults if enabled 2132fe8fb19SBen Gras j ra 2142fe8fb19SBen Gras9: 2152fe8fb19SBen Gras mov.d $f0, $f12 # yes, result is just x 2162fe8fb19SBen Gras j ra 2172fe8fb19SBen GrasEND(ldexp) 218