home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c082_122 / 2.ddi / MATHSRC.ZIP / FBSTP.ASM < prev    next >
Encoding:
Assembly Source File  |  1992-06-10  |  6.9 KB  |  302 lines

  1. ;[]-----------------------------------------------------------------[]
  2. ;|      FBSTP.ASM                                                    |
  3. ;[]-----------------------------------------------------------------[]
  4.  
  5. ;
  6. ;       C/C++ Run Time Library - Version 5.0
  7. ;       Copyright (c) 1987, 1992 by Borland International
  8. ;       All Rights Reserved.
  9.  
  10.         include rules.asi
  11.  
  12.         emul            ; generated emulated instructions
  13.  
  14. ld_temp        STRUC
  15.         ld_fraction     dw      ?
  16.                         dw      ?
  17.                         dw      ?
  18.                         dw      ?
  19.         ld_exponent     dw      ?
  20. ld_temp ENDS
  21.  
  22.  
  23. Code_Seg@
  24.  
  25. ; void _fbstp  ( long double z, short *packedDecimal)
  26.  
  27. ; This is a helper function for __xcvt() used only on Windows,
  28. ; which currently doesn't emulate the FBSTP instruction.
  29. ;
  30. ; It pops and converts the floating point number on the top of the x87
  31. ; stack to a packed decimal integer, storing the result at ES:DI.
  32.  
  33. ; int exp;              /* exponent part of z */
  34. ; short frac[4];        /* fractional part of z */
  35. ; short res[5]          /* packed BCD number */
  36.  
  37. ; void PutFourDigits ( int rem, int posn )
  38.  
  39. ;     res.digits [posn] = rem % 10;
  40. ;     rem = rem / 10;
  41. ;     res.digits [posn+1] = rem % 10;
  42. ;     rem = rem / 10;
  43. ;     res.digits [posn+2] = rem % 10;
  44. ;     res.digits [posn+3] = rem / 10;
  45.  
  46. PutFourDigits   PROC    ;  rem in DX, posn in DI
  47.  
  48.         push    ax
  49.         push    cx
  50.  
  51.         mov     al, 100
  52.         mov     cl, 4
  53.         xchg    ax, dx
  54.  
  55.         div     dl
  56.         mov     dl, ah
  57.         aam                     ; AH, AL = AL DIV 10, AL MOD 10
  58.         shl     ah, cl
  59.         or      ah, al
  60.         xchg    ax, dx
  61.         aam
  62.         shl     ah, cl
  63.         or      al, ah
  64.         mov     ah, dh
  65.         stosw
  66.  
  67.         pop     cx
  68.         pop     ax
  69.         ret
  70.  
  71. PutFourDigits   ENDP
  72.  
  73.  
  74. ; exp  = z.exp;
  75. ; frac = z.frac;
  76.  
  77. ; if (exp < 1) res = 0;
  78.  
  79. ; else if (exp > 60) res = +infinity;
  80.  
  81. ; else
  82. ;     while (exp < 64)
  83. ;         frac = frac DIV 2;
  84. ;         exp  = exp + 1;
  85.  
  86. ;     frac = frac + carry; /* rounding */
  87.  
  88. ;     res = 0;
  89.  
  90. ;     PutFourDigits (frac % 10000, 0);
  91. ;     frac = frac / 10000;
  92. ;     PutFourDigits (frac % 10000, 4);
  93. ;     frac = frac / 10000;
  94. ;     PutFourDigits (frac % 10000, 8);
  95. ;     frac = frac / 10000;
  96. ;     PutFourDigits (frac % 10000, 12);
  97. ;     frac = frac / 10000;
  98.  
  99. ;     res.digits [16] = frac % 10;
  100. ;     res.digits [17] = frac / 10;
  101.  
  102. ;     res.sign = z.sign;
  103.  
  104. ;     return res;
  105.  
  106.         public  __fbstp
  107. __fbstp PROC    NEAR
  108.  
  109. ; Convert floating point value on TOS to packed BCD at ES:DI
  110.  
  111.         push    bp
  112.         mov     bp, sp
  113.         push    si                      ; save SI
  114.         push    di                      ; ES:DI points to result
  115. po?zPtr equ     ([bp - 4].w0)
  116.  
  117.         cld                             ; forward string direction
  118.  
  119. ; exp  = z.exp;
  120. ; frac = z.frac;
  121.  
  122.         FSTP    tbyte ptr es:[di]       ; value is converted in place
  123.         FWAIT
  124.         mov     ax, es:[di].ld_exponent
  125.         and     ax, 07fffh              ; remove sign bit
  126.         sub     ax, 03ffeh              ; subtract (bias+1)
  127.         mov     bx, es:[di].ld_fraction.w0
  128.         mov     cx, es:[di].ld_fraction.w1
  129.         mov     dx, es:[di].ld_fraction.w3
  130.         mov     si, es:[di].ld_fraction.w2
  131.  
  132.  
  133. ; if (exp < 1)
  134. ;    res = 0
  135. ;
  136. ; /* will the result exceed 999,999,999,999,999,999 ? */
  137. ; else (z > [3C, DE0B 6B3A 763F FFF0])
  138. ;    res = +infinity
  139.  
  140.         cmp     ax, 0
  141.         jl      po@underflowJmp
  142.  
  143.         sub     ax, 3Ch
  144.         jl      po@inRange
  145.         jg      po@overflowJmp
  146.         cmp     dx, 0DE0Bh
  147.         jb      po@inRange
  148.         ja      po@overflowJmp
  149.         cmp     si, 06B3Ah
  150.         jb      po@inRange
  151.         ja      po@overflowJmp
  152.         cmp     cx, 0763Fh
  153.         jb      po@inRange
  154.         ja      po@overflowJmp
  155.         cmp     bx, 0FFF0h
  156.         ja      po@overflowJmp
  157.  
  158.  
  159. ; else
  160. ;     while (exp < 64)
  161. ;         frac = frac / 2;
  162. ;         exp  = exp + 1;
  163.  
  164. po@inRange:
  165.         mov     ah, 0                           ; excess precision for rounding
  166.         sub     al, 4
  167.  
  168. po@wordAlign:
  169.         add     al, 16
  170.         jg      po@bitAlign
  171.  
  172.         mov     ah, bh
  173.         mov     bx, cx
  174.         mov     cx, si
  175.         mov     si, dx
  176.         sub     dx, dx
  177.         jmp     po@wordAlign
  178.  
  179. ;----
  180. po@underflowJmp:        jmp     short   po@underflow
  181. po@overflowJmp:         jmp     short   po@overflow
  182. ;----
  183.  
  184. po@bitAlign:
  185.         sub     al, 16
  186.         jnl     po@aligned
  187. po@anotherBit:
  188.         shr     dx, 1
  189.         rcr     si, 1
  190.         rcr     cx, 1
  191.         rcr     bx, 1
  192.         rcr     ah, 1
  193.         inc     al
  194.         jl      po@anotherBit
  195.  
  196. po@aligned:
  197.  
  198. ;     frac = frac + carry; /* rounding */
  199.  
  200.         add     ah, ah
  201.         adc     bx, 0
  202.         adc     cx, 0
  203.         adc     si, 0
  204.         adc     dx, 0           ; DX:SI:CX:BX is now an integer < 2^60
  205.  
  206. ;     PutFourDigits (frac % 10000, 0);
  207. ;     frac = frac / 10000;
  208.  
  209.                                 ; DX < 4096 since 2^60 = 4096 * 2^48
  210.         xchg    ax, si
  211.         mov     si, 10000
  212.         div     si
  213.         xchg    ax, cx
  214.         div     si
  215.         xchg    ax, bx
  216.         div     si              ; frac = CX:BX:AX < 2^47, DX = mod 10000
  217.  
  218.         call    PutFourDigits   ; DX is parameter
  219.  
  220. ;     PutFourDigits (frac % 10000, 4);
  221. ;     frac = frac / 10000;
  222.  
  223.         sub     dx, dx
  224.         xchg    ax, cx
  225.         div     si
  226.         xchg    ax, bx
  227.         div     si
  228.         xchg    ax, cx
  229.         div     si              ; frac = BX:CX:AX < 2^34, DX = mod 10000
  230.  
  231.         call    PutFourDigits   ; DX is parameter
  232.  
  233. ;     PutFourDigits (frac % 10000, 8);
  234. ;     frac = frac / 10000;
  235.  
  236.         mov     dx, bx
  237.         xchg    ax, cx
  238.         div     si
  239.         xchg    ax, cx
  240.         div     si              ; frac = CX:AX < 2^20, DX = mod 10000
  241.  
  242.         call    PutFourDigits   ; DX is parameter
  243.  
  244.  
  245. ;     PutFourDigits (frac % 10000, 12);
  246. ;     frac = frac / 10000;
  247.  
  248.         mov     dx, cx
  249.         div     si              ; frac = AX < 2^7, DX = mod 10000
  250.  
  251.         call    PutFourDigits   ; DX is parameter
  252.  
  253. ;     res.digits [16] = frac % 10;
  254. ;     res.digits [17] = frac / 10;
  255.  
  256.         aam                     ; AH, AL = AL / 10, AL % 10
  257.         mov     cl, 4
  258.         shl     ah, cl
  259.         or      al, ah
  260.         stosb
  261.  
  262. po@end:
  263.  
  264. ;     res.sign = z.sign;
  265.  
  266.         mov     si, po?zPtr
  267.         mov     al, es:[si].ld_exponent.by1
  268.         and     al, 080h        ; isolate sign bit
  269.         stosb
  270.  
  271.         pop     di
  272.         pop     si
  273.         pop     bp
  274.         ret
  275.  
  276. ; ----
  277.  
  278. po@underflow:
  279.         mov     al, 0
  280.  
  281. po@extreme:
  282.         mov     cx, 9
  283. rep     stosb
  284.         jmp     short   po@end
  285.  
  286.  
  287. po@overflow:
  288.         mov     al, 99h
  289.         jmp     short   po@extreme
  290.  
  291.  
  292. ; ----
  293.  
  294.  
  295. __fbstp endp
  296.  
  297. Code_EndS@
  298.  
  299.         end
  300.