xref: /original-bsd/lib/libc/tahoe/fpe/addd.s (revision 3b839eee)
1831b8fa9Sbostic/*
2*3b839eeeSbostic * Copyright (c) 1986, 1993
3*3b839eeeSbostic *	The Regents of the University of California.  All rights reserved.
4831b8fa9Sbostic *
5831b8fa9Sbostic * This code is derived from software contributed to Berkeley by
6831b8fa9Sbostic * Computer Consoles Inc.
7831b8fa9Sbostic *
881274476Sbostic * %sccs.include.redist.c%
9831b8fa9Sbostic */
10831b8fa9Sbostic
11831b8fa9Sbostic#if defined(SYSLIBC_SCCS) && !defined(lint)
12*3b839eeeSbostic	.asciz "@(#)addd.s	8.1 (Berkeley) 06/04/93"
13831b8fa9Sbostic#endif /* SYSLIBC_SCCS and not lint */
143b185fb9Ssam
153b185fb9Ssam#include <tahoemath/fp.h>
163b185fb9Ssam#include "DEFS.h"
173b185fb9Ssam
183b185fb9SsamXENTRY(addd, R2|R3|R4|R5|R6|R7|R8|R9|R10)
193b185fb9Ssam/*
203b185fb9Ssam * see which operand has a greater exponent
213b185fb9Ssam * The greater one will be fetched into r0,r1,r2,r3.
223b185fb9Ssam * r0,r1 - 'pure' fraction, r2 - exponent, r3 - sign).
233b185fb9Ssam * The smaller operand will be fetched into r4,r5,r6,r7.
243b185fb9Ssam */
253b185fb9Ssam	andl3	$EXPMASK,4(fp),r0
263b185fb9Ssam	andl3	$EXPMASK,12(fp),r1
273b185fb9Ssam	cmpl	r0,r1
283b185fb9Ssam	jgtr	first_greater
293b185fb9Ssam
303b185fb9Ssam	movl	12(fp),r0	# bigger operand to r0,r1
313b185fb9Ssam	movl	16(fp),r1
323b185fb9Ssam
333b185fb9Ssam	movl	4(fp),r4	# smaller operand to r4,r5
343b185fb9Ssam	movl	8(fp),r5
353b185fb9Ssam	jmp	expo
363b185fb9Ssam
373b185fb9Ssamfirst_greater:
383b185fb9Ssam	movl	4(fp),r0	# bigger operand to r0,r1
393b185fb9Ssam	movl	8(fp),r1
403b185fb9Ssam
413b185fb9Ssam	movl	12(fp),r4	# smaller operand to r4,r5
423b185fb9Ssam	movl	16(fp),r5
433b185fb9Ssam
443b185fb9Ssam/*
453b185fb9Ssam * compute exponents:
463b185fb9Ssam */
473b185fb9Ssamexpo:
483b185fb9Ssam	andl3	$EXPMASK,r0,r2	# r2 will hold the exponent.
493b185fb9Ssam	jeql	is_res1		# check for reserved operand.
503b185fb9Ssam	shrl	$EXPSHIFT,r2,r2
513b185fb9Ssam
523b185fb9Ssam
533b185fb9Ssam	andl3	$EXPMASK,r4,r6	# r6 will hold the exponent.
543b185fb9Ssam	jeql	is_res2		# check for reserved operand.
553b185fb9Ssam	shrl	$EXPSHIFT,r6,r6
563b185fb9Ssam/*
573b185fb9Ssam * compare the exponents:
583b185fb9Ssam */
593b185fb9Ssam	subl3	r6,r2,r8
603b185fb9Ssam	jeql	signs
613b185fb9Ssam	cmpl	r8,$MAX_EXP_DIF
623b185fb9Ssam	jlss	signs
633b185fb9Ssam	ret			# return the bigger number.
643b185fb9Ssam
653b185fb9Ssam/*
663b185fb9Ssam * remember the signs:
673b185fb9Ssam */
683b185fb9Ssamsigns:
693b185fb9Ssam	clrl	r3
703b185fb9Ssam	bbc	$31,r0,sign2	# if negative remember it.
713b185fb9Ssam	incl	r3
723b185fb9Ssamsign2:
733b185fb9Ssam	clrl	r7
743b185fb9Ssam	bbc	$31,r4,frac	# if negative remember it.
753b185fb9Ssam	incl	r7
763b185fb9Ssam/*
773b185fb9Ssam * compute 'pure' fraction:
783b185fb9Ssam */
793b185fb9Ssamfrac:
803b185fb9Ssam				# clear the non fraction parts.
813b185fb9Ssam	andl2	$(0!(EXPMASK | SIGNBIT)),r0
823b185fb9Ssam				# add the hidden bit.
833b185fb9Ssam	orl2	$(0!CLEARHID),r0
843b185fb9Ssam				# clear the non fraction parts.
853b185fb9Ssam	andl2	$(0!(EXPMASK | SIGNBIT)),r4
863b185fb9Ssam				# add the hidden bit.
873b185fb9Ssam	orl2	$(0!CLEARHID),r4
883b185fb9Ssam
893b185fb9Ssam/*
903b185fb9Ssam * shift the smaller operand:
913b185fb9Ssam */
923b185fb9Ssam	shrq	r8,r4,r4
933b185fb9Ssameql_exps:
943b185fb9Ssam	cmpl 	r3,r7
953b185fb9Ssam	jeql	add
963b185fb9Ssam	bbc	$0,r3,negr4r5
973b185fb9Ssam/*
983b185fb9Ssam * negate the pair r0,r1:
993b185fb9Ssam */
1003b185fb9Ssam	clrl	r3
1013b185fb9Ssam	mcoml	r1,r1
1023b185fb9Ssam	clrl	r9		# r9 - carry flag.
1033b185fb9Ssam	incl	r1
1043b185fb9Ssam	bcc	comr0
1053b185fb9Ssam	incl	r9		# remember the carry.
1063b185fb9Ssamcomr0:	mcoml	r0,r0
1073b185fb9Ssam	bbc	$0,r9,add
1083b185fb9Ssam	incl	r0
1093b185fb9Ssam
1103b185fb9Ssam/*
1113b185fb9Ssam * add the fractions:
1123b185fb9Ssam */
1133b185fb9Ssamadd:
1143b185fb9Ssam	clrl	r10 		# to remember the sign of the result.
1153b185fb9Ssam	addl2	r5,r1
1163b185fb9Ssam	adwc	r4,r0
1173b185fb9Ssam	jgeq	norm		# if positive go to normelize.
1183b185fb9Ssam	incl	r10		# else remember it and negate the result.
1193b185fb9Ssam/*
1203b185fb9Ssam * negate the pair r0,r1:
1213b185fb9Ssam */
1223b185fb9Ssam	clrl	r3
1233b185fb9Ssam	mcoml	r1,r1
1243b185fb9Ssam	clrl	r9		# r9 - carry flag.
1253b185fb9Ssam	incl	r1
1263b185fb9Ssam	bcc	comr00
1273b185fb9Ssam	incl	r9		# remember the carry.
1283b185fb9Ssamcomr00:	mcoml	r0,r0
1293b185fb9Ssam	bbc	$0,r9,norm
1303b185fb9Ssam	incl	r0
1313b185fb9Ssamnorm:	callf	$4,fnorm
1323b185fb9Ssam
1333b185fb9Ssam/*
1343b185fb9Ssam * add the sign bit
1353b185fb9Ssam */
1363b185fb9Ssam	bbs	$0,r10,negative
1373b185fb9Ssam	bbs	$0,r3,negative
1383b185fb9Ssam	ret
1393b185fb9Ssamnegative:
1403b185fb9Ssam	orl2	$SIGNBIT,r0
1413b185fb9Ssam	ret
1423b185fb9Ssam
1433b185fb9Ssam
1443b185fb9Ssam/*
1453b185fb9Ssam * negate the pair r4,r5:
1463b185fb9Ssam */
1473b185fb9Ssamnegr4r5:
1483b185fb9Ssam	clrl	r7
1493b185fb9Ssam	mcoml	r5,r5
1503b185fb9Ssam	clrl	r9		# r9 - carry flag.
1513b185fb9Ssam	incl	r5
1523b185fb9Ssam	bcc	comr4
1533b185fb9Ssam	incl	r9		# remember the carry.
1543b185fb9Ssamcomr4:	mcoml	r4,r4
1553b185fb9Ssam	bbc	$0,r9,add
1563b185fb9Ssam	incl	r4
1573b185fb9Ssam	jmp	add
1583b185fb9Ssam
1593b185fb9Ssam
1603b185fb9Ssamis_res1:
1613b185fb9Ssam	bbs	$31,r0,res_op
1623b185fb9Ssam	movl	r4,r0		# return the  smaller operand.
1633b185fb9Ssam	movl	r5,r1
1643b185fb9Ssam	ret
1653b185fb9Ssam
1663b185fb9Ssamis_res2:
1673b185fb9Ssam	bbs	$31,r4,res_op
1683b185fb9Ssam	ret			# we allready have the 'result' in r0,r1.
1693b185fb9Ssam
1703b185fb9Ssamres_op:
1713b185fb9Ssam	callf	$4,fpresop
1723b185fb9Ssam	ret
173