xref: /minix3/lib/libc/arch/mips/gen/ldexp.S (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
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