|
|
1.1 root 1: .data
2: .asciz "@(#)Ffltd.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: /*
9: * double-precision floating math run-time support
10: *
11: * copyright 1981, 1982 Richard E. James III
12: * translated to SUN idiom 10/11 March 1983 rt
13: * parameter passing re-done 22 July 1983 rt
14: */
15: #include "fpcrtdefs.h"
16:
17: SAVEMASK = 0x3c00
18: RESTMASK = 0x003c
19:
20: /*
21: * type conversion operators
22: *
23: * integer-to-double conversion: fflti
24: * input:
25: * d0 integer
26: * output:
27: * d0/d1 double floating value
28: */
29:
30: RTENTRY(Ffltd)
31: movel d0,a0 | a0 saves x.
32: movel d2,a1 | a1 saves d2.
33: movel #0x41e,d2 | d2 accumulates exponent.
34: tstl d0
35: bpls 3f | Branch if x is non-negative.
36: negl d0 | d0 gets abs(x).
37: 3:
38: bmis 2f | Branch if d0 is normalized.
39: bnes 1f | Branch if x not zero.
40: clrl d1
41: bras Ffltddone | Branch if zero.
42: 1:
43: subqw #1,d2 | Adjust exponent.
44: lsll #1,d0 | Normalize.
45: bpls 1b | Branch if already normalized.
46: 2:
47: bclr #31,d0 | Clear I bit.
48: movel d0,d1 | d1 gets significand.
49: lsrl #8,d0 | Align high order bits.
50: lsrl #3,d0 | Align high order bits.
51: swap d2
52: lsll #4,d2 | Align exponent.
53: orl d2,d0 | Stick exponent.
54: movel #21,d2
55: lsll d2,d1 | Align low order bits.
56: cmpl #0,a0
57: bges Ffltddone | Branch if x was non-negative.
58: bset #31,d0 | Set sign if negative.
59: Ffltddone:
60: movel a1,d2 | Restore d2.
61: RET
62:
63: /*
64: * double-to-integer conversion: ffixi
65: * input:
66: * d0/d1 double floating value
67: * output:
68: * d0 integer
69: */
70:
71: RTENTRY(Fintd)
72: moveml d2-d3,sp@-
73: movel d0,d3 | d3 gets top(x).
74: bclr #31,d0 | d0 gets top(abs(x)).
75: cmpl #0x3ff00000,d0
76: bges 1f | Branch if abs(x) >= 1.
77: clrl d0
78: bras Fintddone
79: 1:
80: cmpl #0x41f00000,d0
81: blts 2f | Branch if 1 <= |x| < 2**32.
82: movel #0x80000000,d0 | Maximum negative integer.
83: bras Fintddone
84: 2:
85: movel d0,d2 | d2 gets abs(x).
86: andl #0xfffff,d0 | Clear sign and exponent.
87: bset #20,d0 | Set I bit.
88: roll #8,d2
89: roll #4,d2
90: andw #0xfff,d2 | d2 gets biased exponent.
91: subw #0x3ff+20,d2
92: bges 3f | Branch if exp >= 20.
93: negw d2
94: lsrl d2,d0
95: bras Fintdsign
96: 3:
97: beqs Fintdsign | Branch if exponent = 20 exactly.
98: lsll d2,d0 | Upper shift.
99: negw d2
100: addw #32,d2 | Compute right shift.
101: lsrl d2,d1 | This part goes from lower to upper.
102: orl d1,d0
103: Fintdsign:
104: tstl d3
105: bpls Fintddone | Branch if x was not negative.
106: negl d0
107: Fintddone:
108: moveml sp@+,d2-d3
109: RET
110:
111: RTENTRY(Fnintd)
112: moveml d2-d4,sp@-
113: movel d0,d3 | d3 gets top(x).
114: bclr #31,d0 | d0 gets top(abs(x)).
115: cmpl #0x3fe00000,d0
116: bges 1f | Branch if abs(x) >= 0.5.
117: clrl d0
118: bras Fnintddone
119: 1:
120: cmpl #0x41f00000,d0
121: blts 2f | Branch if 0.5 <= |x| < 2**32.
122: movel #0x80000000,d0 | Maximum negative integer.
123: bras Fnintddone
124: 2:
125: movel d0,d2 | d2 gets abs(x).
126: andl #0xfffff,d0 | Clear sign and exponent.
127: bset #20,d0 | Set I bit.
128: roll #8,d2
129: roll #4,d2
130: andw #0xfff,d2 | d2 gets biased exponent.
131: subw #0x3ff+20,d2
132: bges 3f | Branch if exp >= 20.
133: negw d2
134: subqw #1,d2
135: lsrl d2,d0 | Upper part.
136: addql #1,d0 | Round bit.
137: lsrl #1,d0 | Finish shift.
138: bras Fnintdsign
139: 3:
140: beqs Fnintdround | Branch if exponent = 20 exactly.
141: movel d1,d4 | d4 will get lower to upper part.
142: lsll d2,d0 | Upper shift.
143: lsll d2,d1 | Lower shift.
144: negw d2
145: addw #32,d2 | Compute right shift.
146: lsrl d2,d4 | This part goes from lower to upper.
147: orl d4,d0
148: Fnintdround:
149: addl #0x80000000,d1
150: bccs Fnintdsign | Branch if no rounding carry propagate.
151: addql #1,d0
152: Fnintdsign:
153: tstl d3
154: bpls Fnintddone | Branch if x was not negative.
155: negl d0
156: Fnintddone:
157: moveml sp@+,d2-d4
158: RET
159:
160: RTENTRY(Frintd)
161: moveml d2-d4,sp@-
162: movel d0,d3 | d3 gets top(x).
163: bclr #31,d0 | d0 gets top(abs(x)).
164: cmpl #0x3fe00000,d0
165: bges 1f | Branch if abs(x) >= 0.5.
166: clrl d0
167: bras Fnintddone
168: 1:
169: cmpl #0x41f00000,d0
170: blts 2f | Branch if 0.5 <= |x| < 2**32.
171: movel #0x80000000,d0 | Maximum negative integer.
172: bras Fnintddone
173: 2:
174: movel d0,d2 | d2 gets abs(x).
175: andl #0xfffff,d0 | Clear sign and exponent.
176: bset #20,d0 | Set I bit.
177: roll #8,d2
178: roll #4,d2
179: andw #0xfff,d2 | d2 gets biased exponent.
180: subw #0x3ff+20,d2
181: bges 3f | Branch if exp >= 20.
182: movel d1,d4 | d4 saves lower part.
183: movel d0,d1
184: negw d2
185: lsrl d2,d0 | Upper part.
186: negw d2
187: addw #32,d2
188: lsll d2,d1 | Lower part.
189: tstl d4
190: beqs Frintdround | Branch if original low part clear.
191: bset #30,d1 | Set sticky bit to influence rounding.
192: bras Frintdround
193: 3:
194: beqs Frintdround | Branch if exponent = 20 exactly.
195: movel d1,d4 | d4 will get lower to upper part.
196: lsll d2,d0 | Upper shift.
197: lsll d2,d1 | Lower shift.
198: negw d2
199: addw #32,d2 | Compute right shift.
200: lsrl d2,d4 | This part goes from lower to upper.
201: orl d4,d0
202: Frintdround:
203: addl #0x80000000,d1
204: jcc Fnintdsign | Branch if no rounding carry propagate.
205: addql #1,d0
206: tstl d1
207: jne Fnintdsign | Branch if not ambiguous.
208: bclr #0,d0 | Force round to even.
209: jra Fnintdsign
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.