home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / zip / gnu / mntlib16.lzh / MNTLIB16 / _NORMSF.S < prev    next >
Text File  |  1993-07-29  |  3KB  |  117 lines

  1. | single floating point normalization routine
  2. |
  3. | written by Kai-Uwe Bloem (I5110401@dbstu1.bitnet).
  4. | Based on a 80x86 floating point packet from comp.os.minix, written by P.Housel
  5. |
  6. |
  7. | Revision 1.4, kub 03-90 :
  8. | export ___normsf entry to C language. Rename the internal entry to a name
  9. | not accessible from C to prevent crashes
  10. |
  11. | Revision 1.3, kub 01-90 :
  12. | added support for denormalized numbers
  13. |
  14. | Revision 1.2, kub 01-90 :
  15. | replace far shifts by swaps to gain speed
  16. |
  17. | Revision 1.1, kub 12-89 :
  18. | Ported over to 68k assembler
  19. |
  20. | Revision 1.0:
  21. | original 8088 code from P.S.Housel
  22.  
  23.     .text
  24.     .even
  25.     .globl    __infinitysf
  26.     .globl    ___normsf
  27.     .globl    norm_sf
  28.  
  29.     | C entry, for procs dealing with the internal representation :
  30.     | float __normsf(long mant, short exp, short sign, short rbits);
  31. ___normsf:
  32.     lea    sp@(4),a0    | parameter pointer
  33.     moveml    d2-d5,sp@-    | save working registers
  34.     movel    a0@+,d4        | get mantissa
  35.     movew    a0@+,d0        | get exponent
  36.     movew    a0@+,d2        | get sign
  37.     movew    a0@+,d1        | rounding information
  38.  
  39.     | internal entry for floating point package, saves time
  40.     | d0=u.exp, d2=u.sign, d1=rounding bits, d4/d5=mantissa
  41.     | registers d2-d7 must be saved on the stack !
  42. norm_sf:
  43.     tstl    d4        | rounding and u.mant == 0 ?
  44.     bne    0f
  45.     tstb    d1
  46.     beq    retz
  47. 0:
  48.     clrb    d2        | "sticky byte"
  49.     movel    #0xff000000,d5
  50. 1:    tstw    d0        | divide (shift)
  51.     ble    0f        |  denormalized number
  52.     movel    d4,d3
  53.     andl    d5,d3        |  or until no bits above 23
  54.     beq    2f
  55. 0:    addw    #1,d0        | increment exponent
  56.     lsrl    #1,d4
  57.     orb    d1,d2        | set "sticky"
  58.     roxrb    #1,d1        | shift into rounding bits
  59.     bra    1b
  60. 2:
  61.     andb    #1,d2
  62.     orb    d2,d1        | make least sig bit "sticky"
  63.     movel    #0xff800000,d5
  64. 3:    movel    d4,d3        | multiply (shift) until
  65.     andl    d5,d3        | one in "implied" position
  66.     bne    4f
  67.     subw    #1,d0        | decrement exponent
  68.     beq    4f        |  too small. store as denormalized number
  69.     addb    d1,d1        | some doubt about this one *
  70.     addxl    d4,d4
  71.     bra    3b
  72. 4:
  73.     tstb    d1        | check rounding bits
  74.     bge    6f        | round down - no action neccessary
  75.     negb    d1
  76.     bvc    5f        | round up
  77.     bclr    #0,d4        | tie case - round to even
  78.     bra    6f
  79. 5:
  80.     clrw    d1        | zero rounding bits
  81.     addl    #1,d4
  82.     tstw    d0
  83.     bne    0f        | renormalize if number was denormalized
  84.     addw    #1,d0        | correct exponent for denormalized numbers
  85.     bra    1b
  86. 0:    movel    d4,d3        | check for rounding overflow
  87.     andl    #0xff000000,d3
  88.     bne    1b        | go back and renormalize
  89. 6:
  90.     tstl    d4        | check if normalization caused an underflow
  91.     beq    retz
  92.     cmpw    #0,d0        | check for exponent overflow or underflow
  93.     blt    retz
  94.     cmpw    #255,d0
  95.     bge    oflow
  96.  
  97.     lslw    #7,d0        | re-position exponent
  98.     andw    #0x8000,d2    | sign bit
  99.     orw    d2,d0
  100.     swap    d0        | map to upper word
  101.     clrw    d0
  102.     andl    #0x7fffff,d4    | top mantissa bits
  103.     orl    d4,d0        | insert exponent and sign
  104.     moveml    sp@+,d2-d5
  105.     rts
  106.  
  107. retz:    clrl    d0
  108.     moveml    sp@+,d2-d5
  109.     rts
  110.  
  111. oflow:    movel    __infinitysf,d0    | return infinty value
  112.     moveml    sp@+,d2-d5    | should really cause trap ?!?
  113.     rts
  114.  
  115. __infinitysf:            | +infinity as proposed by IEEE
  116.     .long    0x7f800000
  117.