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