Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. ;   ix87 specific implementation of pow function.
  2. ;   Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
  3. ;   This file is part of the GNU C Library.
  4. ;   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
  5.  
  6. ;   The GNU C Library is free software; you can redistribute it and/or
  7. ;   modify it under the terms of the GNU Library General Public License as
  8. ;   published by the Free Software Foundation; either version 2 of the
  9. ;   License, or (at your option) any later version.
  10.  
  11. ;   The GNU C Library is distributed in the hope that it will be useful,
  12. ;   but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ;   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14. ;   Library General Public License for more details.
  15.  
  16. ;   You should have received a copy of the GNU Library General Public
  17. ;   License along with the GNU C Library; see the file COPYING.LIB.  If not,
  18. ;   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  19. ;   Boston, MA 02111-1307, USA.  */
  20.  
  21. format MS COFF
  22.  
  23. include 'proc32.inc'
  24.  
  25. section '.text' code readable executable
  26.  
  27. ;public _pow_test@8
  28.  
  29. public _scalbn
  30.  
  31. align 4
  32. proc _scalbn
  33.                   fild  dword [esp+12]
  34.                   fld   qword [esp+4]
  35.                   fscale
  36.                   fstp  st1
  37.                   ret
  38. endp
  39.  
  40. proc _pow_test@8 stdcall x:dword, y:dword
  41.            fld [x]
  42.            fld [y]             
  43.            jmp __CIpow
  44.  
  45.  
  46.  __CIpow:
  47. ;       fldl    12(%esp)        // y
  48.  
  49.         fxam
  50.  
  51.         fnstsw ax
  52.         mov dl,ah
  53.         and ah, 0x45
  54.         cmp ah, 0x40      ; is y == 0 ?
  55.         je .L_11
  56.  
  57.         cmp ah, 0x05      ; is y == ±inf ?
  58.         je .L_12
  59.  
  60.         cmp ah, 0x01      ; is y == NaN ?
  61.         je .L_30
  62.  
  63.         fxch
  64.  
  65.         sub  esp, 8
  66.  
  67.         fxam
  68.         fnstsw ax
  69.         mov dh, ah
  70.         and ah, 0x45
  71.         cmp ah, 0x40
  72.         je  .L_20          ; x is ±0
  73.  
  74.         cmp ah, 0x05
  75.         je  .L_15          ; x is ±inf
  76.  
  77.         fxch               ; y : x
  78.  
  79. ; First see whether `y' is a natural number.  In this case we
  80. ; can use a more precise algorithm.  */
  81.  
  82.         fld st                ; y : y : x
  83.         fistp qword [esp]     ; y : x
  84.         fild  qword [esp]     ; int(y) : y : x
  85.         fucomp  st1           ; y : x
  86.         fnstsw ax
  87.         sahf
  88.         jne .L_2
  89.  
  90. ; OK, we have an integer value for y.  */
  91.  
  92.         pop eax
  93.         pop edx
  94.         or edx,0
  95.         fstp st0              ; x
  96.         jns .L_4              ; y >= 0, jump
  97.         fidiv dword [one]     ; 1/x          (now referred to as x)
  98.         neg eax
  99.         adc edx,0
  100.         neg edx
  101. .L_4:
  102.         fld1                  ; 1 : x
  103.         fxch
  104. .L_6:
  105.         shrd edx, eax,1
  106.         jnc .L_5
  107.         fxch
  108.         fmul st1,st0            ; x : ST*x
  109.         fxch
  110. .L_5:
  111.         fmul st0, st0        ; x*x : ST*x
  112.         shr edx,1
  113.         mov ecx, eax
  114.         or  ecx, edx
  115.         jnz .L_6
  116.         fstp st0            ; ST*x
  117. .L_30:
  118.         ret
  119.  
  120. align 4
  121.  
  122. ; y is a real number.  */
  123.  
  124. .L_2:
  125.         fxch                    ; x : y
  126.         fld1                    ; 1.0 : x : y
  127.         fld      st1            ; x : 1.0 : x : y
  128.         fsub     st0,st1        ; x-1 : 1.0 : x : y
  129.         fabs                    ; |x-1| : 1.0 : x : y
  130.         fcomp qword [limit]     ; 1.0 : x : y
  131.         fnstsw  ax
  132.         fxch                    ; x : 1.0 : y
  133.         sahf
  134.         ja .L_7
  135.         fsub st0, st1           ; x-1 : 1.0 : y
  136.         fyl2xp1                 ; log2(x) : y
  137.         jmp .L_8
  138. .L_7:
  139.         fyl2x                   ; log2(x) : y
  140. .L_8:
  141.         fmul     st0,st1        ; y*log2(x) : y
  142.         fst      st1            ; y*log2(x) : y*log2(x)
  143.         frndint                 ; int(y*log2(x)) : y*log2(x)
  144.         fsubr    st1, st0       ; int(y*log2(x)) : fract(y*log2(x))
  145.         fxch                    ; fract(y*log2(x)) : int(y*log2(x))
  146.         f2xm1                   ; 2^fract(y*log2(x))-1 : int(y*log2(x))
  147.         fld1
  148.         faddp                   ; 2^fract(y*log2(x)) : int(y*log2(x))
  149.         fscale                  ; 2^fract(y*log2(x))*2^int(y*log2(x)) : int(y*log2(x))
  150.         add esp,8
  151.         fstp st1                ; 2^fract(y*log2(x))*2^int(y*log2(x))
  152.         ret
  153.  
  154.  
  155. align 4
  156.  ;       // pow(x,±0) = 1
  157.  
  158. .L_11:
  159.         fstp st0              ; pop y
  160.         fld1
  161.         ret
  162.  
  163. align 4
  164.  
  165. ; y == ±inf
  166.  
  167. .L_12:
  168.         fstp st0              ; pop y
  169. ;        fld   4(%esp)          ; x
  170.         fabs
  171.         fcomp qword [one]       ; < 1, == 1, or > 1
  172.         fnstsw ax
  173.         and ah,0x45
  174.         cmp ah,0x45
  175.         je  .L_13               ; jump if x is NaN
  176.  
  177.         cmp ah,0x40
  178.         je  .L_14               ; jump if |x| == 1
  179.  
  180.         shl ah, 1
  181.         xor ah, dl
  182.         and edx, 2
  183.         fld qword [inf_zero+edx+4]
  184.         ret
  185.  
  186. align 4
  187. .L_14:
  188.         fld  qword [infinity]
  189.         fmul qword [zero]        ; raise invalid exception
  190.         ret
  191.  
  192. align 4
  193. .L_13:
  194. ;        //fld 4(%esp)         // load x == NaN
  195.         ret
  196.  
  197. align 4
  198. ;        // x is ±inf
  199. .L_15:
  200.         fstp st0               ; y
  201.         test dh, 2
  202.         jz   .L_16               ; jump if x == +inf
  203.  
  204. ;  We must find out whether y is an odd integer.
  205.         fld st                   ; y : y
  206.         fistp qword [esp]        ; y
  207.         fild qword [esp]        ; int(y) : y
  208.         fucompp                  ; <empty>
  209.         fnstsw ax
  210.         sahf
  211.         jne .L_17
  212.  
  213. ; OK, the value is an integer, but is the number of bits small
  214. ; enough so that all are coming from the mantissa?
  215.         pop   eax
  216.         pop   edx
  217.         and   al, 1
  218.         jz   .L_18             ;// jump if not odd
  219.         mov  eax, edx
  220.         or   edx, eax
  221.         jns  .L_155
  222.         neg  eax
  223. .L_155:
  224.         cmp  eax, 0x00200000
  225.         ja  .L_18             ;// does not fit in mantissa bits
  226. ; It's an odd integer.
  227.         shr edx, 31
  228.         fld qword [minf_mzero+edx+8]
  229.         ret
  230.  
  231. align 4
  232.  
  233. .L_16:
  234.         fcomp qword [zero]
  235.         add   esp, 8
  236.         fnstsw ax
  237.         shr eax, 5
  238.         and eax, 8
  239.         fld qword [inf_zero+eax+1]
  240.         ret
  241.  
  242. align 4
  243. .L_17:
  244.         shl edx, 30             ;// sign bit for y in right position
  245.         add esp ,8
  246. .L_18:
  247.         shr edx, 31
  248.         fld qword [inf_zero+edx+8]
  249.         ret
  250.  
  251. align 4
  252.                                ; x is ±0
  253. .L_20:
  254.         fstp    st0          ; y
  255.         test    dl,2
  256.         jz      .L_21          ; y > 0
  257.  
  258.  ;x is ±0 and y is < 0.  We must find out whether y is an odd integer.
  259.         test   dh, 2
  260.         jz     .L_25
  261.  
  262.         fld     st             ; y : y
  263.         fistp qword [esp]     ; y
  264.         fild  qword [esp]     ; int(y) : y
  265.         fucompp                ; <empty>
  266.         fnstsw  ax
  267.         sahf
  268.         jne     .L_26
  269.  
  270.    ;OK, the value is an integer, but is the number of bits small
  271.    ;enough so that all are coming from the mantissa?
  272.  
  273.         pop    eax
  274.         pop    edx
  275.         and    al, 1
  276.         jz     .L_27            ; jump if not odd
  277.         cmp    edx,0xffe00000
  278.         jbe    .L_27             ; does not fit in mantissa bits
  279.  
  280. ; It's an odd integer.
  281. ; Raise divide-by-zero exception and get minus infinity value.
  282.  
  283.         fld1
  284.         fdiv qword [zero]
  285.         fchs
  286.         ret
  287.  
  288. .L_25:
  289.         fstp    st0
  290. .L_26:
  291.         add    esp,8
  292. .L_27:
  293.  
  294.  ;Raise divide-by-zero exception and get infinity value.
  295.  
  296.         fld1
  297.         fdiv qword [zero]
  298.         ret
  299.  
  300. align 4
  301.  
  302. ; x is ±0 and y is > 0.  We must find out whether y is an odd integer.
  303.  
  304. .L_21:
  305.         test    dh,2
  306.         jz      .L_22
  307.  
  308.         fld     st              ; y : y
  309.         fistp qword [esp]       ; y
  310.         fild  qword [esp]       ; int(y) : y
  311.         fucompp                 ; <empty>
  312.         fnstsw ax
  313.         sahf
  314.         jne    .L_23
  315.  
  316. ; OK, the value is an integer, but is the number of bits small
  317. ; enough so that all are coming from the mantissa?
  318.  
  319.         pop    eax
  320.         pop    edx
  321.         and    al,1
  322.         jz     .L_24             ; jump if not odd
  323.         cmp    edx,0xffe00000
  324.         jae    .L_24             ; does not fit in mantissa bits
  325.  
  326.  ; It's an odd integer.
  327.  
  328.                fld  qword [mzero]
  329.         ret
  330.  
  331. .L_22:
  332.         fstp    st0
  333. .L_23:
  334.         add     esp,8             ; Don't use 2 x pop
  335. .L_24:
  336.         fldz
  337.         ret
  338. endp
  339.  
  340. align 4
  341.  
  342. inf_zero:
  343. infinity:
  344.            db 0,0,0,0,0,0,0xf0,0x7f
  345. zero:      dq 0.0
  346. minf_mzero:
  347. minfinity:
  348.            db 0,0,0,0,0,0,0xf0,0xff
  349. mzero:
  350.            db 0,0,0,0,0,0,0,0x80
  351. one:
  352.            dq  1.0
  353. limit:
  354.            dq 0.29
  355.  
  356.