1*34438Sbostic/* 2*34438Sbostic * Copyright (c) 1988 Regents of the University of California. 3*34438Sbostic * All rights reserved. 4*34438Sbostic * 5*34438Sbostic * This code is derived from software contributed to Berkeley by 6*34438Sbostic * Computer Consoles Inc. 7*34438Sbostic * 8*34438Sbostic * Redistribution and use in source and binary forms are permitted 9*34438Sbostic * provided that this notice is preserved and that due credit is given 10*34438Sbostic * to the University of California at Berkeley. The name of the University 11*34438Sbostic * may not be used to endorse or promote products derived from this 12*34438Sbostic * software without specific prior written permission. This software 13*34438Sbostic * is provided ``as is'' without express or implied warranty. 14*34438Sbostic */ 1529696Ssam 16*34438Sbostic#if defined(LIBC_SCCS) && !defined(lint) 17*34438Sbostic_sccsid:.asciz "@(#)ldexp.s 1.2 (Berkeley) 05/23/88" 18*34438Sbostic#endif /* LIBC_SCCS and not lint */ 19*34438Sbostic 2029696Ssam/* 2129696Ssam * double ldexp (value, exp) 2229696Ssam * double value; 2329696Ssam * int exp; 2429696Ssam * 2529696Ssam * Ldexp returns value*2**exp, if that result is in range. 2629696Ssam * If underflow occurs, it returns zero. If overflow occurs, 2729696Ssam * it returns a value of appropriate sign and largest 2829696Ssam * possible magnitude. In case of either overflow or underflow, 2929696Ssam * the external int "errno" is set to ERANGE. Note that errno is 3029696Ssam * not modified if no error occurs, so if you intend to test it 3129696Ssam * after you use ldexp, you had better set it to something 3229696Ssam * other than ERANGE first (zero is a reasonable value to use). 3329696Ssam * 3429696Ssam * Constants 3529696Ssam */ 3629696Ssam#include <errno.h> 3729696Ssam#include <tahoemath/fp.h> 3829696Ssam 3929696Ssam#include "DEFS.h" 4029696Ssam 4129696SsamENTRY(ldexp, 0) 4229696Ssam movl 4(fp),r0 /* Fetch "value" */ 4329696Ssam movl 8(fp),r1 4429696Ssam 4529696Ssam andl3 $EXPMASK,r0,r2 /* r2 := shifted biased exponent */ 4629696Ssam jeql ld1 /* If it's zero, we're done */ 4729696Ssam shar $EXPSHIFT,r2,r2 /* shift to get value of exponent */ 4829696Ssam 4929696Ssam addl2 12(fp),r2 /* r2 := new biased exponent */ 5029696Ssam jleq under /* if it's <= 0, we have an underflow */ 5129696Ssam cmpl r2,$256 /* Otherwise check if it's too big */ 5229696Ssam jgeq over /* jump if overflow */ 5329696Ssam/* 5429696Ssam* Construct the result and return 5529696Ssam*/ 5629696Ssam andl2 $0!EXPMASK,r0 /* clear old exponent */ 5729696Ssam shal $EXPSHIFT,r2,r2 /* Put the exponent back in the result */ 5829696Ssam orl2 r2,r0 5929696Ssamld1: ret 6029696Ssam/* 6129696Ssam* Underflow 6229696Ssam*/ 6329696Ssamunder: clrl r0 /* Result is zero */ 6429696Ssam clrl r1 6529696Ssam jbr err /* Join general error code */ 6629696Ssam/* 6729696Ssam* Overflow 6829696Ssam*/ 6929696Ssamover: movl huge0,r0 /* Largest possible floating magnitude */ 7029696Ssam movl huge1,r1 7129696Ssam jbc $31,4(fp),err /* Jump if argument was positive */ 7229696Ssam orl2 $SIGNBIT,r0 /* If arg < 0, make result negative */ 7329696Ssam 7429696Ssamerr: movl $ERANGE,_errno /* Indicate range error */ 7529696Ssam ret 7629696Ssam 7729696Ssam .data 7829696Ssam .globl _errno /* error flag */ 7929696Ssamhuge0: .word 0x7fff /* The largest number that can */ 8029696Ssam .word 0xffff /* be represented in a long floating */ 8129696Ssamhuge1: .word 0xffff /* number. */ 8229696Ssam .word 0xffff 83