134438Sbostic/* 2*61183Sbostic * Copyright (c) 1988, 1993 3*61183Sbostic * The Regents of the University of California. All rights reserved. 434438Sbostic * 534438Sbostic * This code is derived from software contributed to Berkeley by 634438Sbostic * Computer Consoles Inc. 746166Sbostic * 846166Sbostic * %sccs.include.redist.c% 934438Sbostic */ 1029696Ssam 1134438Sbostic#if defined(LIBC_SCCS) && !defined(lint) 12*61183Sbostic .asciz "@(#)ldexp.s 8.1 (Berkeley) 06/04/93" 1334438Sbostic#endif /* LIBC_SCCS and not lint */ 1434438Sbostic 1529696Ssam/* 1629696Ssam * double ldexp (value, exp) 1729696Ssam * double value; 1829696Ssam * int exp; 1929696Ssam * 2029696Ssam * Ldexp returns value*2**exp, if that result is in range. 2129696Ssam * If underflow occurs, it returns zero. If overflow occurs, 2229696Ssam * it returns a value of appropriate sign and largest 2329696Ssam * possible magnitude. In case of either overflow or underflow, 2429696Ssam * the external int "errno" is set to ERANGE. Note that errno is 2529696Ssam * not modified if no error occurs, so if you intend to test it 2629696Ssam * after you use ldexp, you had better set it to something 2729696Ssam * other than ERANGE first (zero is a reasonable value to use). 2829696Ssam * 2929696Ssam * Constants 3029696Ssam */ 3142188Sbostic 3242188Sbostic/* 3342188Sbostic * we can't include errno.h anymore, ANSI says that it defines errno. 3442188Sbostic * 3542188Sbostic * #include <errno.h> 3642188Sbostic */ 3742188Sbostic#define ERANGE 34 3845946Sbostic#include <tahoe/math/fp.h> 3929696Ssam 4029696Ssam#include "DEFS.h" 4129696Ssam 4229696SsamENTRY(ldexp, 0) 4329696Ssam movl 4(fp),r0 /* Fetch "value" */ 4429696Ssam movl 8(fp),r1 4529696Ssam 4629696Ssam andl3 $EXPMASK,r0,r2 /* r2 := shifted biased exponent */ 4729696Ssam jeql ld1 /* If it's zero, we're done */ 4829696Ssam shar $EXPSHIFT,r2,r2 /* shift to get value of exponent */ 4929696Ssam 5029696Ssam addl2 12(fp),r2 /* r2 := new biased exponent */ 5129696Ssam jleq under /* if it's <= 0, we have an underflow */ 5229696Ssam cmpl r2,$256 /* Otherwise check if it's too big */ 5329696Ssam jgeq over /* jump if overflow */ 5429696Ssam/* 5529696Ssam* Construct the result and return 5629696Ssam*/ 5729696Ssam andl2 $0!EXPMASK,r0 /* clear old exponent */ 5829696Ssam shal $EXPSHIFT,r2,r2 /* Put the exponent back in the result */ 5929696Ssam orl2 r2,r0 6029696Ssamld1: ret 6129696Ssam/* 6229696Ssam* Underflow 6329696Ssam*/ 6429696Ssamunder: clrl r0 /* Result is zero */ 6529696Ssam clrl r1 6629696Ssam jbr err /* Join general error code */ 6729696Ssam/* 6829696Ssam* Overflow 6929696Ssam*/ 7029696Ssamover: movl huge0,r0 /* Largest possible floating magnitude */ 7129696Ssam movl huge1,r1 7229696Ssam jbc $31,4(fp),err /* Jump if argument was positive */ 7329696Ssam orl2 $SIGNBIT,r0 /* If arg < 0, make result negative */ 7429696Ssam 7529696Ssamerr: movl $ERANGE,_errno /* Indicate range error */ 7629696Ssam ret 7729696Ssam 7829696Ssam .data 7929696Ssam .globl _errno /* error flag */ 8029696Ssamhuge0: .word 0x7fff /* The largest number that can */ 8129696Ssam .word 0xffff /* be represented in a long floating */ 8229696Ssamhuge1: .word 0xffff /* number. */ 8329696Ssam .word 0xffff 84