xref: /original-bsd/lib/libc/tahoe/fpe/addd.s (revision f052b07a)
1#ifdef LIBC_SCCS
2	.asciz	"@(#)addd.s	1.1 (Berkeley/CCI) 07/02/86"
3#endif LIBC_SCCS
4
5#include <tahoemath/fp.h>
6#include "DEFS.h"
7
8XENTRY(addd, R2|R3|R4|R5|R6|R7|R8|R9|R10)
9/*
10 * see which operand has a greater exponent
11 * The greater one will be fetched into r0,r1,r2,r3.
12 * r0,r1 - 'pure' fraction, r2 - exponent, r3 - sign).
13 * The smaller operand will be fetched into r4,r5,r6,r7.
14 */
15	andl3	$EXPMASK,4(fp),r0
16	andl3	$EXPMASK,12(fp),r1
17	cmpl	r0,r1
18	jgtr	first_greater
19
20	movl	12(fp),r0	# bigger operand to r0,r1
21	movl	16(fp),r1
22
23	movl	4(fp),r4	# smaller operand to r4,r5
24	movl	8(fp),r5
25	jmp	expo
26
27first_greater:
28	movl	4(fp),r0	# bigger operand to r0,r1
29	movl	8(fp),r1
30
31	movl	12(fp),r4	# smaller operand to r4,r5
32	movl	16(fp),r5
33
34/*
35 * compute exponents:
36 */
37expo:
38	andl3	$EXPMASK,r0,r2	# r2 will hold the exponent.
39	jeql	is_res1		# check for reserved operand.
40	shrl	$EXPSHIFT,r2,r2
41
42
43	andl3	$EXPMASK,r4,r6	# r6 will hold the exponent.
44	jeql	is_res2		# check for reserved operand.
45	shrl	$EXPSHIFT,r6,r6
46/*
47 * compare the exponents:
48 */
49	subl3	r6,r2,r8
50	jeql	signs
51	cmpl	r8,$MAX_EXP_DIF
52	jlss	signs
53	ret			# return the bigger number.
54
55/*
56 * remember the signs:
57 */
58signs:
59	clrl	r3
60	bbc	$31,r0,sign2	# if negative remember it.
61	incl	r3
62sign2:
63	clrl	r7
64	bbc	$31,r4,frac	# if negative remember it.
65	incl	r7
66/*
67 * compute 'pure' fraction:
68 */
69frac:
70				# clear the non fraction parts.
71	andl2	$(0!(EXPMASK | SIGNBIT)),r0
72				# add the hidden bit.
73	orl2	$(0!CLEARHID),r0
74				# clear the non fraction parts.
75	andl2	$(0!(EXPMASK | SIGNBIT)),r4
76				# add the hidden bit.
77	orl2	$(0!CLEARHID),r4
78
79/*
80 * shift the smaller operand:
81 */
82	shrq	r8,r4,r4
83eql_exps:
84	cmpl 	r3,r7
85	jeql	add
86	bbc	$0,r3,negr4r5
87/*
88 * negate the pair r0,r1:
89 */
90	clrl	r3
91	mcoml	r1,r1
92	clrl	r9		# r9 - carry flag.
93	incl	r1
94	bcc	comr0
95	incl	r9		# remember the carry.
96comr0:	mcoml	r0,r0
97	bbc	$0,r9,add
98	incl	r0
99
100/*
101 * add the fractions:
102 */
103add:
104	clrl	r10 		# to remember the sign of the result.
105	addl2	r5,r1
106	adwc	r4,r0
107	jgeq	norm		# if positive go to normelize.
108	incl	r10		# else remember it and negate the result.
109/*
110 * negate the pair r0,r1:
111 */
112	clrl	r3
113	mcoml	r1,r1
114	clrl	r9		# r9 - carry flag.
115	incl	r1
116	bcc	comr00
117	incl	r9		# remember the carry.
118comr00:	mcoml	r0,r0
119	bbc	$0,r9,norm
120	incl	r0
121norm:	callf	$4,fnorm
122
123/*
124 * add the sign bit
125 */
126	bbs	$0,r10,negative
127	bbs	$0,r3,negative
128	ret
129negative:
130	orl2	$SIGNBIT,r0
131	ret
132
133
134/*
135 * negate the pair r4,r5:
136 */
137negr4r5:
138	clrl	r7
139	mcoml	r5,r5
140	clrl	r9		# r9 - carry flag.
141	incl	r5
142	bcc	comr4
143	incl	r9		# remember the carry.
144comr4:	mcoml	r4,r4
145	bbc	$0,r9,add
146	incl	r4
147	jmp	add
148
149
150is_res1:
151	bbs	$31,r0,res_op
152	movl	r4,r0		# return the  smaller operand.
153	movl	r5,r1
154	ret
155
156is_res2:
157	bbs	$31,r4,res_op
158	ret			# we allready have the 'result' in r0,r1.
159
160res_op:
161	callf	$4,fpresop
162	ret
163