|
|
1.1 root 1: .data
2: .asciz "@(#)Fadds.s 1.1 86/02/03 Copyr 1985 Sun Micro"
3: .even
4: .text
5:
6: | Copyright (c) 1985 by Sun Microsystems, Inc.
7:
8: #include "fpcrtdefs.h"
9:
10: /*
11: * ieee single floating run-time support
12: * copyright 1981, Richard E. James III
13: * translated to SUN idiom 14 March 1983 rt
14: */
15:
16: /* single floating addition and subtraction */
17: /*
18: * entry conditions:
19: * first argument in d0
20: * second argument in d1
21: * exit conditions:
22: * result (4 bytes) in d0
23: *
24: * register conventions:
25: * d0 operand 1
26: * d1 operand 2/sum
27: * d2 sign of operand 1
28: * d3 sign of operand 2
29: * d4 exponent of operand 1
30: * d5 exponent of operand 2
31: * d6 difference of exponents
32: * d7 reserved for sticky
33: */
34: SAVEMASK = 0x3f00 | registers d2-d7
35: RESTMASK = 0xfc
36: NSAVED = 6*4 | 6 registers * sizeof(register)
37:
38: RTENTRY(Fsubs)
39: bchg #31,d1
40: jra adding
41: RTENTRY(Fadds)
42: adding:
43: | save registers and load operands into registers
44: moveml #SAVEMASK,sp@- | registers d2-d7
45: | extract signs
46: asll #1,d0 | sign ->c
47: scs d2 | c -> d4
48: asll #1,d1
49: scs d3
50: | compare and exchange to put larger in d0
51: cmpl d1,d0
52: blss 1$
53: exg d0,d1
54: exg d2,d3
55: | extract exponents
56: 1$: roll #8,d1
57: roll #8,d0
58: clrl d5
59: movb d1,d5 | larger exp
60: clrw d4
61: movb d0,d4 | smaller exp
62: bnes 3$ | not zero or denormalized
63: | smaller is 0 or is denormalized
64: tstl d0 | if smaller == 0
65: jeq signofzero | then use larger (sign of 0-0 unpredictable)
66: tstb d5 | larger exponent
67: bnes 4$ | not gu
68: | both are denormalized
69: cmpb d3,d2 | compare signs
70: bnes 2$
71: addl d0,d1
72: addxb d1,d1 | incr exp to 1 if overflow
73: jra asbuild
74: 2$: subl d0,d1 | subtract
75: jne asbuild
76: jra cancel
77: | neither is denormalized
78: 3$: movb #1,d0 | clear exp and
79: rorl #1,d0
80: 4$: movb #1,d1 | ... clr hidden bit
81: rorl #1,d1
82: cmpb #0xff,d5
83: jeq ovfl | inf or nan
84: | align smaller
85: movw d5,d6
86: subw d4,d6 | difference of exponents
87: cmpw #16,d6
88: bges bigshift | Branch if shift 26 or more places.
89: check8: cmpw #8,d6
90: blts shortshift | exit when <8 *s
91: tstb d0
92: beqs shift8 | Branch if no bits to be lost.
93: bset #8,d0 | Sticky bit on.
94: shift8:
95: subqw #8,d6
96: lsrl #8,d0 | align
97: bra check8 | loop
98: bigshift:
99: cmpw #26,d6
100: bges greatshift | Branch if only sticky left.
101: tstw d0
102: beqs 1$
103: bset #16,d0 | Set sticky bit.
104: 1$:
105: clrw d0
106: swap d0
107: subw #16,d6
108: bras check8
109: greatshift:
110: moveq #1,d0 | Here's a sticky bit.
111: bras addorsub
112: shortshift:
113: movb d0,d7
114: lsrl d6,d0 | finish align
115: cmpw #2,d6
116: bges stickit | Branch if shift >=2 so whole byte sticky.
117: andb #1,d7 | Shift = 0 or 1 so only lsb sticks.
118: stickit:
119: tstb d7
120: beqs addorsub | Branch if no bits to stick.
121: bset #0,d0 | Set a sticky bit on.
122: addorsub:
123: cmpb d3,d2 | cmp signs
124: bnes diff | decide whether to add or subtract
125:
126: | add them
127: addl d0,d1 | sum
128: bccs endas | no carry here
129: roxrl #1,d1 | pull in overflow *s
130: addqw #1,d5
131: cmpw #0xff,d5
132: blts endas | no ofl
133: bras a_geninf
134:
135:
136: signofzero: | Set proper sign of zero.
137: cmpb d2,d3
138: beqs usel | If signs are equal, use d3.
139: tstl d1
140: bnes usel | Branch if not zero.
141: clrb d3 | Sign if positive otherwise.
142: bras usel
143:
144: | subtract them
145: diff: subl d0,d1
146: bmis endas | if normalized
147: beqs cancel | result == 0
148: 9$: asll #1,d1 | normalize
149: dbmi d5,9$ | dec exponent
150: subqw #1,d5
151: bgts endas | not gu
152: beqs 10$
153: clrw d5
154: lsrl #1,d1 | grad und
155: 10$: lsrl #1,d1
156:
157: endas: | round (NOT FULLY STANDARD)
158: addl #0x80,d1 | round
159: bccs testeven | round did not cause mantissa to ofl
160: roxrl #1,d1
161: addqw #1,d5
162: cmpw #0xff,d5
163: beqs a_geninf | round caused exp to overflow
164: bras rebuild
165: testeven: | Test if ambiguous case.
166: tstb d1
167: bnes rebuild | Branch if not ambiguous.
168: bclr #8,d1 | Force round to even.
169: rebuild: | rebuild answer
170: lsll #1,d1 | toss hidden
171: usel: movb d5,d1 | insert exponent
172: asbuild:rorl #8,d1
173: roxrb #1,d3
174: roxrl #1,d1 | apply sign
175: | d1 now has answer
176: movl d1,d0
177: asexit:
178: moveml sp@+,#RESTMASK
179: RET
180:
181: | EXCEPTION CASES
182: ovfl: | largest exponent = 255
183: lsll #1,d1
184: tstl d1 | larger mantissa
185: bnes usel | larger == nan
186: cmpb d4,d5 | exps
187: bnes usel | larger == inf
188: | AFFINE MODE ASSUMED IN THIS IMPLEMENTATION
189: cmpb d3,d2 | signs
190: beqs usel | inf+inf = inf
191: |gennan:
192: movl #0x7f800001,d0
193: bras asexit
194:
195: | complete cancellation
196: cancel: clrl d0 | result == 0
197: | need minus 0 for (-0)+(-0), round to -inf
198: bras asexit
199: | result overflows:
200: a_geninf:movl #0xff,d1
201: bras asbuild
202:
203:
204: /*
205: * ieee single floating compare
206: * copyright 1981, Richard E. James III
207: * translated to SUN idiom 29 March 1983 rt
208: */
209:
210: /*
211: * entry conditions:
212: * first argument in d0
213: * second argument in d1
214: * exit conditions:
215: * result in condition code
216: * d0/d1 trashed
217: *
218: * register conventions:
219: * d0 operand 1
220: * d1 operand 2
221: * d2 scratch
222: */
223: NSAVED = 4
224: CODE = NSAVED
225:
226: RTENTRY(Fcmps)
227: #ifdef PROF
228: unlk a6 | don't get in the way of the cc.
229: #endif
230: subqw #2,sp | save space for condition code return
231: movl d2,sp@- | save register
232:
233: movl d1,d2
234: andl d0,d2 | compare signs
235: bpls 1$
236: exg d0,d1 | both minus
237: 1$: cmpl d1,d0 | main compare
238: bgts 1f
239: blts 2f
240: movw #FEQ,sp@(CODE)
241: bras 3f
242: 1:
243: movw #FGT,sp@(CODE)
244: bras 3f
245: 2:
246: movw #FLT,sp@(CODE)
247: 3:
248: lsll #1,d0
249: lsll #1,d1
250: cmpl d1,d0
251: bccs 2$
252: exg d0,d1 | find larger
253: 2$: cmpl #0xff000000,d0
254: blss 3$
255: | nan
256: movw #FUN,sp@(CODE) | c for unordered
257: 3$: tstl d0
258: bnes 4$
259: movw #FEQ,sp@(CODE) | -0 == 0
260: | result is in sp@(CODE)
261: 4$: | restore saved register and go
262: movl sp@+,d2
263: rtr
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.