xref: /original-bsd/sys/tahoe/math/Kaddd.s (revision 7211505a)
1/*	Kaddd.s	1.3	86/01/05	*/
2
3#include "../tahoemath/fp.h"
4#include "../tahoe/SYS.h"
5
6/*
7 * _Kaddd(acc_most,acc_least,op_most,op_least,hfs)
8 */
9
10ENTRY(Kaddd, R10|R9|R8|R7|R6|R5|R4|R3|R2)
11/*
12 * see which operand has a greater exponent
13 * The greater one will be fetched into r0,r1,r2,r3.
14 * r0,r1 - 'pure' fraction, r2 - exponent, r3 - sign).
15 * The smaller operand will be fetched into r4,r5,r6,r7.
16 */
17	tstl	4(fp)	# handle (a+b) where a and/or b = 0.0
18	jneq	next
19	movl	16(fp),r1
20	movl	12(fp),r0
21	ret
22next:
23	tstl	12(fp)
24	jneq	doit
25	movl	8(fp),r1
26	movl	4(fp),r0
27	ret
28doit:
29	andl3	$EXPMASK,4(fp),r0
30	andl3	$EXPMASK,12(fp),r1
31	cmpl	r0,r1
32	jgtr	first_greater
33
34	movl	12(fp),r0	# bigger operand to r0,r1
35	movl	16(fp),r1
36
37	movl	4(fp),r4	# smaller operand to r4,r5
38	movl	8(fp),r5
39	jmp	expo
40
41first_greater:
42	movl	4(fp),r0	# bigger operand to r0,r1
43	movl	8(fp),r1
44
45	movl	12(fp),r4	# smaller operand to r4,r5
46	movl	16(fp),r5
47
48
49/*
50 * Compute exponents:
51 */
52expo:
53	andl3	$EXPMASK,r0,r2	# r2 will hold the exponent.
54	shrl	$EXPSHIFT,r2,r2
55	andl3	$EXPMASK,r4,r6	# r6 will hold the exponent.
56	shrl	$EXPSHIFT,r6,r6
57/*
58 * Compare the exponents:
59 */
60	subl3	r6,r2,r8
61	jeql	signs
62	cmpl	r8,$MAX_EXP_DIF
63	jleq	signs
64	ret			# return the bigger number.
65
66/*
67 * Remember the signs:
68 */
69signs:
70	clrl	r3
71	bbc	$31,r0,sign2	# if negative remember it.
72	incl	r3
73sign2:
74	clrl	r7
75	bbc	$31,r4,frac	# if negative remember it.
76	incl	r7
77/*
78 * Compute 'pure' fraction:
79 */
80frac:
81				# clear the non fraction parts.
82	andl2	$(0!(EXPMASK | SIGNBIT)),r0
83				# add the hidden bit.
84	orl2	$(0!CLEARHID),r0
85				# clear the non fraction parts.
86	andl2	$(0!(EXPMASK | SIGNBIT)),r4
87				# add the hidden bit.
88	orl2	$(0!CLEARHID),r4
89
90/*
91 * Shift the smaller operand:
92 */
93	shrq	r8,r4,r4
94eql_exps:
95	cmpl 	r3,r7
96	jeql	add
97	bbc	$0,r3,negr4r5
98/*
99 * Negate the pair r0,r1:
100 */
101	clrl	r3
102	mcoml	r1,r1
103	clrl	r9		# r9 - carry flag.
104	incl	r1
105	bcc	comr0
106	incl	r9		# remember the carry.
107comr0:	mcoml	r0,r0
108	bbc	$0,r9,add
109	incl	r0
110
111/*
112 * Add the fractions:
113 */
114add:
115	clrl	r10 		# to remember the sign of the result.
116	addl2	r5,r1
117	adwc	r4,r0
118	jgeq	norm		# if positive go to normelize.
119	incl	r10		# else remember it and negate the result.
120/*
121 * Negate the pair r0,r1:
122 */
123	clrl	r3
124	mcoml	r1,r1
125	clrl	r9		# r9 - carry flag.
126	incl	r1
127	bcc	comr00
128	incl	r9		# remember the carry.
129comr00:	mcoml	r0,r0
130	bbc	$0,r9,norm
131	incl	r0
132norm:	pushl	20(fp)		# addr of returnen exception.
133	callf	$8,_Kfnorm
134
135/*
136 * Add the sign bit
137 */
138	bbs	$0,r10,negative
139	bbs	$0,r3,negative
140	ret
141negative:
142	orl2	$SIGNBIT,r0
143	ret
144
145
146/*
147 * Negate the pair r4,r5:
148 */
149negr4r5:
150	clrl	r7
151	mcoml	r5,r5
152	clrl	r9		# r9 - carry flag.
153	incl	r5
154	bcc	comr4
155	incl	r9		# remember the carry.
156comr4:	mcoml	r4,r4
157	bbc	$0,r9,add
158	incl	r4
159	jmp	add
160
161	movl	r4,r0		# return the  smaller operand.
162	movl	r5,r1
163	ret
164