home *** CD-ROM | disk | FTP | other *** search
/ Atari FTP / ATARI_FTP_0693.zip / ATARI_FTP_0693 / Mint / mntlib25.zoo / _normsf.cpp < prev    next >
C/C++ Source or Header  |  1992-12-12  |  4KB  |  163 lines

  1. | mjr: _normsf is not needed if the 68881 is present
  2. | but _infinitysf is retained
  3.  
  4. |#######################################################################
  5.  
  6. | single floating point normalization routine
  7. |
  8. | written by Kai-Uwe Bloem (I5110401@dbstu1.bitnet).
  9. | Based on a 80x86 floating point packet from comp.os.minix, written by P.Housel
  10. | patched by Olaf Flebbe (flebbe@tat.physik.uni-tuebingen.de)
  11. |
  12. | Revision 1.4.2 olaf 11-92
  13. |  + correct stack after overflow.
  14. |
  15. | Revision 1.4.1 olaf 10-92:
  16. |  + corrected rounding in tie case: round up, not down.
  17. |    (needed for enquire 4.3)
  18. |
  19. | Revision 1.4, kub 03-90 :
  20. | export ___normsf entry to C language. Rename the internal entry to a name
  21. | not accessible from C to prevent crashes
  22. |
  23. | Revision 1.3, kub 01-90 :
  24. | added support for denormalized numbers
  25. |
  26. | Revision 1.2, kub 01-90 :
  27. | replace far shifts by swaps to gain speed
  28. |
  29. | Revision 1.1, kub 12-89 :
  30. | Ported over to 68k assembler
  31. |
  32. | Revision 1.0:
  33. | original 8088 code from P.S.Housel
  34.  
  35.     .text
  36.     .even
  37.     .globl    __infinitysf
  38. #if !defined (__M68881__) && !defined (sfp004)
  39.     .globl    ___normsf
  40.     .globl    norm_sf
  41. #include "errbase.h"
  42. #ifdef    ERROR_CHECK
  43. LC0:
  44.     .ascii "normsf: OVERFLOW\12\15\0"
  45.     .even
  46. #endif    ERROR_CHECK
  47.  
  48.     | C entry, for procs dealing with the internal representation :
  49.     | float __normsf(long mant, short exp, short sign, short rbits);
  50. ___normsf:
  51.     lea    sp@(4),a0    | parameter pointer
  52.     moveml    d2-d5,sp@-    | save working registers
  53.     movel    a0@+,d4        | get mantissa
  54.     movew    a0@+,d0        | get exponent
  55.     movew    a0@+,d2        | get sign
  56.     movew    a0@+,d1        | rounding information
  57.  
  58.     | internal entry for floating point package, saves time
  59.     | d0=u.exp, d2=u.sign, d1=rounding bits, d4/d5=mantissa
  60.     | registers d2-d7 must be saved on the stack !
  61. norm_sf:
  62.     tstl    d4        | rounding and u.mant == 0 ?
  63.     bne    0f
  64.     tstb    d1
  65.     beq    retz
  66. 0:
  67.     clrb    d2        | "sticky byte"
  68.     movel    #0xff000000,d5
  69. 1:    tstw    d0        | divide (shift)
  70.     ble    0f        |  denormalized number
  71.     movel    d4,d3
  72.     andl    d5,d3        |  or until no bits above 23
  73.     beq    2f
  74. 0:    addw    #1,d0        | increment exponent
  75.     lsrl    #1,d4
  76.     orb    d1,d2        | set "sticky"
  77.     roxrb    #1,d1        | shift into rounding bits
  78.     bra    1b
  79. 2:
  80.     andb    #1,d2
  81.     orb    d2,d1        | make least sig bit "sticky"
  82.     movel    #0xff800000,d5
  83. 3:    movel    d4,d3        | multiply (shift) until
  84.     andl    d5,d3        | one in "implied" position
  85.     bne    4f
  86.     subw    #1,d0        | decrement exponent
  87.     beq    4f        |  too small. store as denormalized number
  88.     addb    d1,d1        | some doubt about this one *
  89.     addxl    d4,d4
  90.     bra    3b
  91. 4:
  92.     tstb    d1        | check rounding bits
  93.     bge    6f        | round down - no action neccessary
  94.     negb    d1
  95.     bvc    5f        | round up
  96.     movew   d4,d1           | tie case - round to even
  97.                                 | dont need rounding bits any more
  98.     andw    #1,d1           | check if even        
  99.     beq    6f              | mantissa is even - no action necessary
  100.                                 | fall through
  101.  
  102. 5:
  103.     clrw    d1        | zero rounding bits
  104.     addl    #1,d4
  105.     tstw    d0
  106.     bne    0f        | renormalize if number was denormalized
  107.     addw    #1,d0        | correct exponent for denormalized numbers
  108.     bra    1b
  109. 0:    movel    d4,d3        | check for rounding overflow
  110.     andl    #0xff000000,d3
  111.     bne    1b        | go back and renormalize
  112. 6:
  113.     tstl    d4        | check if normalization caused an underflow
  114.     beq    retz
  115.     cmpw    #0,d0        | check for exponent overflow or underflow
  116.     blt    retz
  117.     cmpw    #255,d0
  118.     bge    oflow
  119.  
  120.     lslw    #7,d0        | re-position exponent
  121.     andw    #0x8000,d2    | sign bit
  122.     orw    d2,d0
  123.     swap    d0        | map to upper word
  124.     clrw    d0
  125.     andl    #0x7fffff,d4    | top mantissa bits
  126.     orl    d4,d0        | insert exponent and sign
  127.     moveml    sp@+,d2-d5
  128.     rts
  129.  
  130. retz:    moveq    #ERANGE,d0
  131.     Emove    d0,Errno
  132.     clrl    d0
  133.     moveml    sp@+,d2-d5
  134.     rts
  135.  
  136. oflow:    
  137.  
  138. #ifdef    ERROR_CHECK
  139.     movel    d1,a7@-
  140.     pea    pc@(LC0)
  141.     pea    Stderr
  142.     jbsr    _fprintf    |
  143.     addql    #8,a7        |
  144.     movel    a7@+,d1
  145. #endif    ERROR_CHECK
  146.  
  147. |    movel    pc@(__infinitysf),d0    | return infinity value
  148.     movel   __infinitysf,d0
  149.  
  150.     btst    #15,d2        | transfer sign
  151.     beq    ofl_clear    | (mjr++)
  152.     bset    #31,d0        |
  153.     moveml  sp@+,d2-d5
  154.     rts
  155. ofl_clear:
  156.     moveml    sp@+,d2-d5    | should really cause trap ?!?
  157.     rts
  158.  
  159. #endif __M68881__
  160.  
  161. __infinitysf:            | +infinity as proposed by IEEE
  162.     .long    0x7f800000
  163.