136829Sbostic/* 2*61181Sbostic * Copyright (c) 1986, 1993 3*61181Sbostic * The Regents of the University of California. All rights reserved. 436829Sbostic * 536829Sbostic * This code is derived from software contributed to Berkeley by 636829Sbostic * Computer Consoles Inc. 736829Sbostic * 842637Sbostic * %sccs.include.redist.c% 936829Sbostic */ 1029516Ssam 1136829Sbostic#if defined(SYSLIBC_SCCS) && !defined(lint) 12*61181Sbostic .asciz "@(#)muld.s 8.1 (Berkeley) 06/04/93" 1336829Sbostic#endif /* SYSLIBC_SCCS and not lint */ 1436829Sbostic 1529516Ssam#include <tahoemath/fp.h> 1629516Ssam#include "DEFS.h" 1729516Ssam 1829516Ssam#define HIDDEN 23 /* here we count from 0 not from 1 as in fp.h */ 1929516Ssam 2029516SsamXENTRY(muld, R2|R3|R4|R5|R6|R7|R8|R9) 2129516Ssam clrl r3 /* r3 - sign: 0 for positive,1 for negative. */ 2229516Ssam movl 4(fp),r0 2329516Ssam jgeq 1f 2429516Ssam movl $1,r3 2529516Ssam1: movl 12(fp),r2 2629516Ssam jgeq 2f 2729516Ssam bbc $0,r3,1f /* seconed operand is negative. */ 2829516Ssam clrl r3 /* if first was negative, make result positive. */ 2929516Ssam jmp 2f 3029516Ssam1: movl $1,r3 /* if first was positive, make result negative. */ 3129516Ssam2: andl2 $EXPMASK,r0 /* compute first 'pure'exponent. */ 3229516Ssam jeql is_res1 3329516Ssam shrl $EXPSHIFT,r0,r0 3429516Ssam subl2 $BIASP1,r0 3529516Ssam andl2 $EXPMASK,r2 /* compute seconed 'pure'exponent. */ 3629516Ssam jeql is_res2 3729516Ssam shrl $EXPSHIFT,r2,r2 3829516Ssam subl2 $BIASP1,r2 3929516Ssam addl2 r0,r2 /* add the exponents. */ 4029516Ssam addl2 $(BIASP1+2),r2 4129516Ssam jleq underflow 4229516Ssam cmpl r2,$258 /* normalization can make the exp. smaller. */ 4329516Ssam jgeq overflow 4429516Ssam /* 4529516Ssam * We have the sign in r3,the exponent in r2,now is the time to 4629516Ssam * perform the multiplication... 4729516Ssam */ 4829516Ssam /* fetch first fraction: (r0,r1) */ 4929516Ssam andl3 $(0!(EXPMASK | SIGNBIT)),4(fp),r0 5029516Ssam orl2 $(0!CLEARHID),r0 5129516Ssam movl 8(fp),r1 5229516Ssam shlq $7,r0,r0 /* leave the sign bit cleared. */ 5329516Ssam 5429516Ssam /* fetch seconed fraction: (r4,r5) */ 5529516Ssam andl3 $(0!(EXPMASK | SIGNBIT)),12(fp),r4 5629516Ssam orl2 $(0!CLEARHID),r4 5729516Ssam movl 16(fp),r5 5829516Ssam shlq $7,r4,r4 /* leave the sign bit cleared. */ 5929516Ssam 6029516Ssam /* in the following lp1 stands for least significant part of operand 1, 6129516Ssam * lp2 for least significant part of operand 2, 6229516Ssam * mp1 for most significant part of operand 1, 6329516Ssam * mp2 for most significant part of operand 2. 6429516Ssam */ 6529516Ssam 6629516Ssam clrl r6 6729516Ssam shrl $1,r1,r1 /* clear the sign bit of the lp1. */ 6829516Ssam jeql 1f 6929516Ssam emul r1,r4,$0,r6 /* r6,r7 <-- lp1*mp2 */ 7029516Ssam shlq $1,r6,r6 /* to compensate for the shift we did to clear the sign bit. */ 7129516Ssam1: shrl $1,r5,r5 /* clear the sign bit of the lp2. */ 7229516Ssam jeql 1f 7329516Ssam emul r0,r5,$0,r8 /* r8,r9 <-- mp1*lp2 */ 7429516Ssam shlq $1,r8,r8 7529516Ssam addl2 r9,r7 /* r6,r7 <-- the sum of the products. */ 7629516Ssam adwc r8,r6 7729516Ssam1: emul r0,r4,$0,r0 /* r0,r1 <-- mp1*mp2 */ 7829516Ssam addl2 r6,r1 /* add the most sig. part of the sum. */ 7929516Ssam adwc $0,r0 8029516Ssam movl r0,r4 /* to see how much we realy need to shift. */ 8129516Ssam movl $6,r5 /* r5 - shift counter. */ 8229516Ssam shrl $7,r4,r4 /* dummy shift. */ 8329516Ssam1: bbs $HIDDEN,r4,realshift 8429516Ssam shll $1,r4,r4 8529516Ssam decl r2 /* update exponent. */ 8629516Ssam jeql underflow 8729516Ssam decl r5 /* update shift counter. */ 8829516Ssam jmp 1b 8929516Ssamrealshift: 9029516Ssam shrq r5,r0,r0 9129516Ssam bbc $0,r1,shiftmore 9229516Ssam incl r1 /* rounding. */ 9329516Ssamshiftmore: 9429516Ssam shrq $1,r0,r0 9529516Ssamcomb: 9629516Ssam andl2 $CLEARHID,r0 9729516Ssam shll $EXPSHIFT,r2,r4 9829516Ssam orl2 r4,r0 9929516Ssam cmpl r2,$256 10029516Ssam jlss 1f 10129516Ssam callf $4,fpover 10229516Ssamsign: 10329516Ssam1: bbc $0,r3,done 10429516Ssam orl2 $SIGNBIT,r0 10529516Ssamdone: ret 10629516Ssam 10729516Ssam 10829516Ssam 10929516Ssamis_res1: 11029516Ssam bbc $31,4(fp),retzero 11129516Ssam callf $4,fpresop 11229516Ssam ret 11329516Ssamis_res2: 11429516Ssam bbc $31,12(fp),retzero 11529516Ssam callf $4,fpresop 11629516Ssam ret 11729516Ssam retzero: 11829516Ssam clrl r0 11929516Ssam clrl r1 12029516Ssam ret 12129516Ssam overflow: 12229516Ssam callf $4,fpover 12329516Ssam jmp sign 12429516Ssam underflow: 12529516Ssam callf $4,fpunder 12629516Ssam ret 127