|
|
1.1 ! root 1: .data ! 2: .asciz "@(#)Ffloat.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: * single-precision utility operations ! 12: * ! 13: * copyright 1981, 1982 Richard E. James III ! 14: * translated to SUN idiom 11 March 1983 rt ! 15: */ ! 16: ! 17: NSAVED = 3*4 | save registers d2-d4 ! 18: SAVEMASK = 0x3c00 ! 19: RESTMASK = 0x003c ! 20: ! 21: /* ! 22: * unpack a single-precision number into the unpacked record format: ! 23: * d0/d1 mantissa ! 24: * d2.w exponent ! 25: * d3.w sign in upper bit ! 26: * d3.b type ( zero, gu, plain, inf, nan ) ! 27: */ ! 28: ! 29: ENTER(f_unpk) ! 30: movl d1,d3 ! 31: swap d3 | sign in bit 15 ! 32: lsll #1,d1 | toss sign ! 33: roll #8,d1 ! 34: clrw d2 ! 35: movb d1,d2 | exponent ! 36: bnes 1$ | not gu or zero ! 37: movb #1,d3 ! 38: tstl d1 ! 39: beqs 3$ ! 40: movb #2,d3 | gu -- gradual underflow unnormalized ! 41: bras 3$ ! 42: 1$: cmpb #255,d2 | inf or nan ! 43: bnes 2$ | nope, plain number ! 44: movw #0x6000,d2 ! 45: clrb d1 | erase exponent ! 46: movb #4,d3 | infinity ! 47: tstl d1 ! 48: beqs 4$ ! 49: movb #5,d3 | nan ! 50: bras 4$ ! 51: 2$: movb #1,d1 | hidden bit ! 52: subqw #1,d2 ! 53: movb #3,d3 ! 54: 3$: subw #(126+23),d2 ! 55: 4$: rorl #1,d1 ! 56: lsrl #8,d1 ! 57: clrl d0 ! 58: rts ! 59: ! 60: /* ! 61: * reconstruct a single precision number from its pieces ! 62: * returns packed value in d0 ! 63: */ ! 64: ! 65: ENTER(f_pack) ! 66: movw d2,d4 | exponent ! 67: cmpb #4,d3 | is type inf or nan ? ! 68: blts 1$ | no, then branch ! 69: orl d0,d1 ! 70: orl #0x7f800000,d1 | exponent for inf/nan ! 71: lsll #1,d1 ! 72: bras 6$ ! 73: 1$: ! 74: clrb d2 | for sticky ! 75: tstl d0 ! 76: beqs 3$ ! 77: | shift from upper into lower ! 78: 2$: ! 79: orb d1,d2 | sticky ! 80: movb d0,d1 ! 81: addqw #8,d4 | adjust exponent ! 82: rorl #8,d1 ! 83: lsrl #8,d0 ! 84: bnes 2$ | loop until top == 0 ! 85: 3$: movl d1,d0 ! 86: beqs 6$ ! 87: | find top bit ! 88: bmis 5$ ! 89: 4$: subqw #1,d4 | adjust exponent ! 90: lsll #1,d0 | normalize ! 91: bpls 4$ ! 92: 5$: addw #(126+23+9),d4 ! 93: tstb d2 ! 94: beqs 7$ | Branch if no sticky. ! 95: bset #0,d0 | Turn on sticky bit. ! 96: 7$: ! 97: bsrs f_rcp ! 98: rorl #8,d0 ! 99: movl d0,d1 ! 100: 6$: lslw #1,d3 ! 101: roxrl #1,d1 | append sign ! 102: rts ! 103: ! 104: ! 105: /* ! 106: * round, check for over/underflow, and pack in the exponent. ! 107: */ ! 108: ! 109: ENTER(f_rcp) ! 110: tstl d0 ! 111: bmis f_rcfast ! 112: | do extra normalize ( for mul/div) ! 113: subqw #1,d4 ! 114: lsll #1,d0 | do one normalize ! 115: f_rcfast: ! 116: tstw d4 ! 117: bgts 2$ ! 118: | underflow ! 119: cmpw #-24,d4 ! 120: blts rcpzero ! 121: negb d4 ! 122: addqb #1,d4 ! 123: movl d1,sp@- | Save d1 on stack. ! 124: clrl d1 | d1 gets 0. ! 125: bset d4,d1 | For n bit shift, d1 gets 2**n. ! 126: subql #1,d1 | d1 gets 2**n -1, an n bit field. ! 127: andl d0,d1 | d1 gets bits to be shifted away. ! 128: beqs 1f | Branch if all zero. ! 129: bset d4,d0 | Sticky lsb for bits to be lost. ! 130: 1: ! 131: movl sp@+,d1 | Restore d1. ! 132: lsrl d4,d0 | denormalize ! 133: clrw d4 | exp == 0 ! 134: 2$: addl #0x80,d0 | crude round ! 135: bccs stesteven ! 136: | round overflowed ! 137: roxrl #1,d0 ! 138: addqw #1,d4 ! 139: bras scheckbig ! 140: stesteven: ! 141: tstb d0 | Check extra bits after round. ! 142: bnes scheckbig | Branch if round was not ambiguous. ! 143: bclr #8,d0 | Force round to even. ! 144: scheckbig: ! 145: cmpw #0xff,d4 | adjust exponent ! 146: bges rcpinf ! 147: lsll #1,d0 | toss hidden ! 148: |scs d0 | no hidden implies zero or denormalized ! 149: |andb d4,d0 ! 150: |rts ! 151: bccs rcpsubnorm | Branch if no i bit found, implying zero or subnorm. ! 152: movb d4,d0 | d0 gets exponent. ! 153: bnes rcprts | Branch if exp was not zero, implying normal result. ! 154: movb #1,d0 | Result was subnormal before round, normal after, ! 155: | so adjust exponent accordingly. ! 156: rcprts: ! 157: rts ! 158: rcpsubnorm: | No carry out from shift implies zero or subnormal ! 159: | result after rounding. ! 160: clrb d0 | Set minimum exponent. ! 161: rts ! 162: ! 163: rcpzero: ! 164: clrl d0 ! 165: rts ! 166: rcpinf: ! 167: movl #0xff,d0 | infinity ! 168: rts ! 169: ! 170: NSAVED = 3*4 | save registers d2-d4 ! 171: SAVEMASK = 0x3c00 ! 172: RESTMASK = 0x003c ! 173: ARG2PTR = a0 ! 174: ! 175: /* ! 176: * split a double floating number into its pieces ! 177: * input: ! 178: * d0/d1 double number ! 179: * output: (format of an unpacked record) ! 180: * d0/d1 mantissa: array[1..2] of integer; ! 181: * d2.w exponent: -32768..32767; ! 182: * d3.w sign: (bit 15) 0..1; ! 183: * d3.b type: 1..5; (zero, gu, plain, inf, nan ) ! 184: */ ! 185: ! 186: ENTER(d_unpk) ! 187: movl #0xfff00000,d2 | mask for sign and exponent ! 188: movl d0,d3 ! 189: swap d3 | sign ! 190: andl d0,d2 | extract exponent ! 191: eorl d2,d0 | top of mantissa cleared out ! 192: movl d1,d4 ! 193: orl d0,d4 | non-zero iff mantissa non-zero ! 194: lsll #1,d2 | toss sign ! 195: bnes 1$ | not 0 or gu ! 196: movb #1,d3 ! 197: tstl d4 ! 198: beqs 3$ | zero ! 199: movb #2,d3 ! 200: bras 3$ | gu ! 201: 1$: swap d2 ! 202: lsrw #(16-11),d2 | exp to bottom of register ! 203: cmpw #0x7ff,d2 | inf or nan ! 204: bnes 2$ | plain ! 205: movw #0x6000,d2 ! 206: movb #4,d3 ! 207: tstl d4 ! 208: beqs 4$ | inf ! 209: movb #5,d3 | nan ! 210: bras 4$ ! 211: 2$: bset #20,d0 | hidden bit ! 212: subqw #1,d2 ! 213: movb #3,d3 ! 214: 3$: subw #(1022+52), d2 ! 215: 4$: rts ! 216: ! 217: /* ! 218: * reconstruct a double precision number from a record containing its pieces. ! 219: * ! 220: * input: ! 221: * d2 upper ! 222: * d3 lower ! 223: * d6 exponent ! 224: * output: ! 225: * d0/d1 result ! 226: */ ! 227: ! 228: ENTER(d_pack) ! 229: cmpb #4,d3 | type ! 230: blts 1$ ! 231: orl d1,d0 ! 232: lsll #1,d0 ! 233: orl #0xffe00000,d0 ! 234: bras 2$ | nan or inf ! 235: 1$: addw #(1022+52+12),d2 ! 236: exg d0,d2 ! 237: exg d0,d6 ! 238: exg d1,d3 ! 239: bsrs d_norm ! 240: bsr d_rcp ! 241: movl d0,d6 ! 242: movl d2,d0 ! 243: exg d3,d1 ! 244: 2$: lslw #1,d3 ! 245: roxrl #1,d0 ! 246: rts ! 247: ! 248: /* ! 249: * normalize a double-precision number ! 250: * ! 251: * input: ! 252: * d2/d3 mantissa ! 253: * d6 exponent ! 254: */ ! 255: ! 256: ENTER(d_norm) ! 257: tstl d2 | upper is non-zero ! 258: bnes 1$ ! 259: cmpw #32,d6 ! 260: blts 2$ | about to be denormalized ! 261: subw #32,d6 ! 262: exg d3,d2 | shift 32 ! 263: tstl d2 ! 264: beqs 4$ | if result == 0 ! 265: 1$: bmis 3$ | if already normalized ! 266: 2$: lsll #1,d3 | normalize ! 267: roxll #1,d2 ! 268: dbmi d6,2$ | loop until normalized ! 269: dbpl d6,3$ | make sure d6 decremented ! 270: 3$: rts ! 271: 4$: movw #-2222,d6 | exp == 0 for zero ! 272: rts ! 273: ! 274: ! 275: /* ! 276: * round, check for over/underflow, and pack in the exponent. ! 277: * d_rcp rounds the double value and packs the exponent in, ! 278: * catching infinity, zero, and denormalized numbers. ! 279: * d_usel puts together the larger argument. ! 280: * ! 281: * input: ! 282: * d2/d3 mantissa (- if norm) ! 283: * d6 biased exponent ! 284: * (need sign, sticky) ! 285: * output: ! 286: * d2/d3 most of number, no sign or hidden bit, ! 287: * waiting to shift sign in. ! 288: * other: ! 289: * d4 lost ! 290: * d5 unchanged ! 291: */ ! 292: ! 293: ENTER(d_rcp) ! 294: tstw d6 ! 295: bgts 2$ ! 296: | exponent is negative; denormalize before rounding ! 297: cmpw #-53,d6 ! 298: blts dsigned0| go all the way with zero ! 299: negw d6 ! 300: 1$: lsrl #1,d2 | denormalize ! 301: roxrl #1,d3 ! 302: bccs 1f | Check for bit passing out forever. ! 303: bset #0,d3 | Stick it back on the end. ! 304: 1: dbra d6,1$ ! 305: clrw d6 ! 306: | round ! 307: 2$: addl #0x400,d3 ! 308: bccs testeven | Branch if round did not overflow lower part. ! 309: addql #1,d2 | carry ! 310: bccs testeven | Branch if round did not overflow significand. ! 311: roxrl #1,d2 ! 312: roxrl #1,d3 ! 313: addqw #1,d6 ! 314: bras checkbig ! 315: ! 316: testeven: | Test for ambiguous case to force round to even. ! 317: movw #0x7ff,d4 | d4 gets rounding mask. ! 318: andw d3,d4 | d4 gets extra bits left after rounding. ! 319: bnes checkbig | Branch if it wasn't ambiguous case. ! 320: bclr #11,d3 | Ambiguous case: force round to even. ! 321: ! 322: checkbig: ! 323: cmpw #0x7ff,d6 ! 324: bges drcpbig ! 325: ENTER(d_usel) ! 326: | rebuild answer ! 327: movl #0xfffff800,d4 ! 328: andl d4,d3 ! 329: andl d2,d4 ! 330: eorl d4,d2 ! 331: orl d2,d3 ! 332: movl d4,d2 ! 333: lsll #1,d2 ! 334: |bcss 4$ ! 335: bcss cout | Branch if carry out occurred. ! 336: cmpw #0x7ff,d6 ! 337: beqs 4$ ! 338: clrw d6 ! 339: 4$: ! 340: dshiftright: | Double shift right to pack. ! 341: moveq #11,d4 ! 342: rorl d4,d3 ! 343: orw d6,d2 ! 344: rorl d4,d2 ! 345: rts ! 346: dsigned0: clrl d2 ! 347: clrl d3 ! 348: rts ! 349: drcpbig:movl #0xffe00000,d2 | infinity ! 350: clrl d3 ! 351: rts ! 352: ! 353: cout: ! 354: tstw d6 ! 355: bnes dshiftright | Branch if number was not subnormal. ! 356: movw #1,d6 | Subnormal rounded to normal so fix exp. ! 357: bras dshiftright ! 358: ! 359: | utilities used for floating point routines ! 360: ! 361: ENTER(f_snan) ! 362: movl #0x7fffffff,d0 | Standard 68881 error nan. ! 363: rts ! 364: ! 365: SAVED0D1 = 0x0003 ! 366: RESTD0D1 = 0x0003 ! 367: SAVEALL = 0x3F00 | registers d2-d4 ! 368: RESTALL = 0x00fc ! 369: ! 370: | decode type of arg in d1 and return 1-5 n d0 for zero gu plain inf and nan ! 371: ! 372: ENTER(f_tst) ! 373: lsll #1,d1 | toss sign ! 374: roll #8,d1 | exp in low byte ! 375: tstb d1 ! 376: bnes 1$ | branch if not gu or zero ! 377: movl #1,d0 | assume zero ! 378: tstl d1 ! 379: beqs 3$ | it is ! 380: movl #2,d0 | else it's a gu ! 381: bras 3$ ! 382: 1$: cmpb #255,d1 | inf or nan ? ! 383: bnes 2$ | nope - plain ! 384: movl #4,d0 | assume inf ! 385: andl #0xFFFFFF00,d1 | Clear exponent field. ! 386: beqs 3$ | it is ! 387: movl #5,d0 | else it'a a nan ! 388: rts ! 389: 2$: movl #3,d0 ! 390: 3$: rts ! 391: ! 392: | Single and double unbiased exponent, d0 to d0. ! 393: ! 394: | Fexpos(1.0) = 0 = Fexpod(1.0) ! 395: ! 396: RTENTRY(Fexpos) ! 397: andl #0x7f800000,d0 | Clear out extra bits. ! 398: roll #1,d0 ! 399: roll #8,d0 ! 400: subl #0x7f,d0 ! 401: RET ! 402: ! 403: RTENTRY(Fexpod) ! 404: andl #0x7ff00000,d0 | Clear out extra bits. ! 405: roll #4,d0 ! 406: roll #8,d0 ! 407: subl #0x3ff,d0 ! 408: RET ! 409: ! 410: | Switch mode and status. ! 411: ! 412: RTENTRY(Fmode) ! 413: movel d0,sp@- ! 414: movel _Fmode,d0 ! 415: movel sp@+,_Fmode ! 416: RET ! 417: RTENTRY(Fstatus) ! 418: movel d0,sp@- ! 419: movel _Fstatus,d0 ! 420: movel sp@+,_Fstatus ! 421: RET
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.