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