xref: /csrg-svn/lib/libc/tahoe/fpe/addd.s (revision 61181)
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 */
1029507Ssam
1136829Sbostic#if defined(SYSLIBC_SCCS) && !defined(lint)
12*61181Sbostic	.asciz "@(#)addd.s	8.1 (Berkeley) 06/04/93"
1336829Sbostic#endif /* SYSLIBC_SCCS and not lint */
1436829Sbostic
1529507Ssam#include <tahoemath/fp.h>
1629507Ssam#include "DEFS.h"
1729507Ssam
1829507SsamXENTRY(addd, R2|R3|R4|R5|R6|R7|R8|R9|R10)
1929507Ssam/*
2029507Ssam * see which operand has a greater exponent
2129507Ssam * The greater one will be fetched into r0,r1,r2,r3.
2229507Ssam * r0,r1 - 'pure' fraction, r2 - exponent, r3 - sign).
2329507Ssam * The smaller operand will be fetched into r4,r5,r6,r7.
2429507Ssam */
2529507Ssam	andl3	$EXPMASK,4(fp),r0
2629507Ssam	andl3	$EXPMASK,12(fp),r1
2729507Ssam	cmpl	r0,r1
2829507Ssam	jgtr	first_greater
2929507Ssam
3029507Ssam	movl	12(fp),r0	# bigger operand to r0,r1
3129507Ssam	movl	16(fp),r1
3229507Ssam
3329507Ssam	movl	4(fp),r4	# smaller operand to r4,r5
3429507Ssam	movl	8(fp),r5
3529507Ssam	jmp	expo
3629507Ssam
3729507Ssamfirst_greater:
3829507Ssam	movl	4(fp),r0	# bigger operand to r0,r1
3929507Ssam	movl	8(fp),r1
4029507Ssam
4129507Ssam	movl	12(fp),r4	# smaller operand to r4,r5
4229507Ssam	movl	16(fp),r5
4329507Ssam
4429507Ssam/*
4529507Ssam * compute exponents:
4629507Ssam */
4729507Ssamexpo:
4829507Ssam	andl3	$EXPMASK,r0,r2	# r2 will hold the exponent.
4929507Ssam	jeql	is_res1		# check for reserved operand.
5029507Ssam	shrl	$EXPSHIFT,r2,r2
5129507Ssam
5229507Ssam
5329507Ssam	andl3	$EXPMASK,r4,r6	# r6 will hold the exponent.
5429507Ssam	jeql	is_res2		# check for reserved operand.
5529507Ssam	shrl	$EXPSHIFT,r6,r6
5629507Ssam/*
5729507Ssam * compare the exponents:
5829507Ssam */
5929507Ssam	subl3	r6,r2,r8
6029507Ssam	jeql	signs
6129507Ssam	cmpl	r8,$MAX_EXP_DIF
6229507Ssam	jlss	signs
6329507Ssam	ret			# return the bigger number.
6429507Ssam
6529507Ssam/*
6629507Ssam * remember the signs:
6729507Ssam */
6829507Ssamsigns:
6929507Ssam	clrl	r3
7029507Ssam	bbc	$31,r0,sign2	# if negative remember it.
7129507Ssam	incl	r3
7229507Ssamsign2:
7329507Ssam	clrl	r7
7429507Ssam	bbc	$31,r4,frac	# if negative remember it.
7529507Ssam	incl	r7
7629507Ssam/*
7729507Ssam * compute 'pure' fraction:
7829507Ssam */
7929507Ssamfrac:
8029507Ssam				# clear the non fraction parts.
8129507Ssam	andl2	$(0!(EXPMASK | SIGNBIT)),r0
8229507Ssam				# add the hidden bit.
8329507Ssam	orl2	$(0!CLEARHID),r0
8429507Ssam				# clear the non fraction parts.
8529507Ssam	andl2	$(0!(EXPMASK | SIGNBIT)),r4
8629507Ssam				# add the hidden bit.
8729507Ssam	orl2	$(0!CLEARHID),r4
8829507Ssam
8929507Ssam/*
9029507Ssam * shift the smaller operand:
9129507Ssam */
9229507Ssam	shrq	r8,r4,r4
9329507Ssameql_exps:
9429507Ssam	cmpl 	r3,r7
9529507Ssam	jeql	add
9629507Ssam	bbc	$0,r3,negr4r5
9729507Ssam/*
9829507Ssam * negate the pair r0,r1:
9929507Ssam */
10029507Ssam	clrl	r3
10129507Ssam	mcoml	r1,r1
10229507Ssam	clrl	r9		# r9 - carry flag.
10329507Ssam	incl	r1
10429507Ssam	bcc	comr0
10529507Ssam	incl	r9		# remember the carry.
10629507Ssamcomr0:	mcoml	r0,r0
10729507Ssam	bbc	$0,r9,add
10829507Ssam	incl	r0
10929507Ssam
11029507Ssam/*
11129507Ssam * add the fractions:
11229507Ssam */
11329507Ssamadd:
11429507Ssam	clrl	r10 		# to remember the sign of the result.
11529507Ssam	addl2	r5,r1
11629507Ssam	adwc	r4,r0
11729507Ssam	jgeq	norm		# if positive go to normelize.
11829507Ssam	incl	r10		# else remember it and negate the result.
11929507Ssam/*
12029507Ssam * negate the pair r0,r1:
12129507Ssam */
12229507Ssam	clrl	r3
12329507Ssam	mcoml	r1,r1
12429507Ssam	clrl	r9		# r9 - carry flag.
12529507Ssam	incl	r1
12629507Ssam	bcc	comr00
12729507Ssam	incl	r9		# remember the carry.
12829507Ssamcomr00:	mcoml	r0,r0
12929507Ssam	bbc	$0,r9,norm
13029507Ssam	incl	r0
13129507Ssamnorm:	callf	$4,fnorm
13229507Ssam
13329507Ssam/*
13429507Ssam * add the sign bit
13529507Ssam */
13629507Ssam	bbs	$0,r10,negative
13729507Ssam	bbs	$0,r3,negative
13829507Ssam	ret
13929507Ssamnegative:
14029507Ssam	orl2	$SIGNBIT,r0
14129507Ssam	ret
14229507Ssam
14329507Ssam
14429507Ssam/*
14529507Ssam * negate the pair r4,r5:
14629507Ssam */
14729507Ssamnegr4r5:
14829507Ssam	clrl	r7
14929507Ssam	mcoml	r5,r5
15029507Ssam	clrl	r9		# r9 - carry flag.
15129507Ssam	incl	r5
15229507Ssam	bcc	comr4
15329507Ssam	incl	r9		# remember the carry.
15429507Ssamcomr4:	mcoml	r4,r4
15529507Ssam	bbc	$0,r9,add
15629507Ssam	incl	r4
15729507Ssam	jmp	add
15829507Ssam
15929507Ssam
16029507Ssamis_res1:
16129507Ssam	bbs	$31,r0,res_op
16229507Ssam	movl	r4,r0		# return the  smaller operand.
16329507Ssam	movl	r5,r1
16429507Ssam	ret
16529507Ssam
16629507Ssamis_res2:
16729507Ssam	bbs	$31,r4,res_op
16829507Ssam	ret			# we allready have the 'result' in r0,r1.
16929507Ssam
17029507Ssamres_op:
17129507Ssam	callf	$4,fpresop
17229507Ssam	ret
173