125c28e83SPiotr Jasiukajtis/* 225c28e83SPiotr Jasiukajtis * CDDL HEADER START 325c28e83SPiotr Jasiukajtis * 425c28e83SPiotr Jasiukajtis * The contents of this file are subject to the terms of the 525c28e83SPiotr Jasiukajtis * Common Development and Distribution License (the "License"). 625c28e83SPiotr Jasiukajtis * You may not use this file except in compliance with the License. 725c28e83SPiotr Jasiukajtis * 825c28e83SPiotr Jasiukajtis * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 925c28e83SPiotr Jasiukajtis * or http://www.opensolaris.org/os/licensing. 1025c28e83SPiotr Jasiukajtis * See the License for the specific language governing permissions 1125c28e83SPiotr Jasiukajtis * and limitations under the License. 1225c28e83SPiotr Jasiukajtis * 1325c28e83SPiotr Jasiukajtis * When distributing Covered Code, include this CDDL HEADER in each 1425c28e83SPiotr Jasiukajtis * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1525c28e83SPiotr Jasiukajtis * If applicable, add the following below this CDDL HEADER, with the 1625c28e83SPiotr Jasiukajtis * fields enclosed by brackets "[]" replaced with your own identifying 1725c28e83SPiotr Jasiukajtis * information: Portions Copyright [yyyy] [name of copyright owner] 1825c28e83SPiotr Jasiukajtis * 1925c28e83SPiotr Jasiukajtis * CDDL HEADER END 2025c28e83SPiotr Jasiukajtis */ 2125c28e83SPiotr Jasiukajtis/* 2225c28e83SPiotr Jasiukajtis * Copyright 2011 Nexenta Systems, Inc. All rights reserved. 2325c28e83SPiotr Jasiukajtis */ 2425c28e83SPiotr Jasiukajtis/* 2525c28e83SPiotr Jasiukajtis * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 2625c28e83SPiotr Jasiukajtis * Use is subject to license terms. 2725c28e83SPiotr Jasiukajtis */ 2825c28e83SPiotr Jasiukajtis 2925c28e83SPiotr Jasiukajtis .file "powl.s" 3025c28e83SPiotr Jasiukajtis 3125c28e83SPiotr Jasiukajtis/ Special cases: 3225c28e83SPiotr Jasiukajtis/ 3325c28e83SPiotr Jasiukajtis/ x ** 0 is 1 3425c28e83SPiotr Jasiukajtis/ 1 ** y is 1 (C99) 3525c28e83SPiotr Jasiukajtis/ x ** NaN is NaN 3625c28e83SPiotr Jasiukajtis/ NaN ** y (except 0) is NaN 3725c28e83SPiotr Jasiukajtis/ x ** 1 is x 3825c28e83SPiotr Jasiukajtis/ +-(|x| > 1) ** +inf is +inf 3925c28e83SPiotr Jasiukajtis/ +-(|x| > 1) ** -inf is +0 4025c28e83SPiotr Jasiukajtis/ +-(|x| < 1) ** +inf is +0 4125c28e83SPiotr Jasiukajtis/ +-(|x| < 1) ** -inf is +inf 4225c28e83SPiotr Jasiukajtis/ (-1) ** +-inf is +1 (C99) 4325c28e83SPiotr Jasiukajtis/ +0 ** +y (except 0, NaN) is +0 4425c28e83SPiotr Jasiukajtis/ -0 ** +y (except 0, NaN, odd int) is +0 4525c28e83SPiotr Jasiukajtis/ +0 ** -y (except 0, NaN) is +inf (z flag) 4625c28e83SPiotr Jasiukajtis/ -0 ** -y (except 0, NaN, odd int) is +inf (z flag) 4725c28e83SPiotr Jasiukajtis/ -0 ** y (odd int) is - (+0 ** x) 4825c28e83SPiotr Jasiukajtis/ +inf ** +y (except 0, NaN) is +inf 4925c28e83SPiotr Jasiukajtis/ +inf ** -y (except 0, NaN) is +0 5025c28e83SPiotr Jasiukajtis/ -inf ** +-y (except 0, NaN) is -0 ** -+y (NO z flag) 5125c28e83SPiotr Jasiukajtis/ x ** -1 is 1/x 5225c28e83SPiotr Jasiukajtis/ x ** 2 is x*x 5325c28e83SPiotr Jasiukajtis/ -x ** y (an integer) is (-1)**(y) * (+x)**(y) 5425c28e83SPiotr Jasiukajtis/ x ** y (x negative & y not integer) is NaN (i flag) 5525c28e83SPiotr Jasiukajtis 5625c28e83SPiotr Jasiukajtis#include "libm.h" 5725c28e83SPiotr JasiukajtisLIBM_ANSI_PRAGMA_WEAK(powl,function) 5825c28e83SPiotr Jasiukajtis#include "xpg6.h" 5925c28e83SPiotr Jasiukajtis 6025c28e83SPiotr Jasiukajtis .data 6125c28e83SPiotr Jasiukajtis .align 4 6225c28e83SPiotr Jasiukajtisnegzero: 6325c28e83SPiotr Jasiukajtis .float -0.0 6425c28e83SPiotr Jasiukajtishalf: 6525c28e83SPiotr Jasiukajtis .float 0.5 6625c28e83SPiotr Jasiukajtisone: 6725c28e83SPiotr Jasiukajtis .float 1.0 6825c28e83SPiotr Jasiukajtisnegone: 6925c28e83SPiotr Jasiukajtis .float -1.0 7025c28e83SPiotr Jasiukajtistwo: 7125c28e83SPiotr Jasiukajtis .float 2.0 7225c28e83SPiotr JasiukajtisSnan: 7325c28e83SPiotr Jasiukajtis .long 0x7f800001 7425c28e83SPiotr Jasiukajtispinfinity: 7525c28e83SPiotr Jasiukajtis .long 0x7f800000 7625c28e83SPiotr Jasiukajtisninfinity: 7725c28e83SPiotr Jasiukajtis .long 0xff800000 7825c28e83SPiotr Jasiukajtis 7925c28e83SPiotr Jasiukajtis 8025c28e83SPiotr Jasiukajtis ENTRY(powl) 8125c28e83SPiotr Jasiukajtis pushl %ebp 8225c28e83SPiotr Jasiukajtis movl %esp,%ebp 8325c28e83SPiotr Jasiukajtis PIC_SETUP(1) 8425c28e83SPiotr Jasiukajtis 8525c28e83SPiotr Jasiukajtis fldt 8(%ebp) / x 8625c28e83SPiotr Jasiukajtis fxam / determine class of x 8725c28e83SPiotr Jasiukajtis fnstsw %ax / store status in %ax 8825c28e83SPiotr Jasiukajtis movb %ah,%dh / %dh <- condition code of x 8925c28e83SPiotr Jasiukajtis 9025c28e83SPiotr Jasiukajtis fldt 20(%ebp) / y , x 9125c28e83SPiotr Jasiukajtis fxam / determine class of y 9225c28e83SPiotr Jasiukajtis fnstsw %ax / store status in %ax 9325c28e83SPiotr Jasiukajtis movb %ah,%dl / %dl <- condition code of y 9425c28e83SPiotr Jasiukajtis 9525c28e83SPiotr Jasiukajtis call .pow_main /// LOCAL 9625c28e83SPiotr Jasiukajtis PIC_WRAPUP 9725c28e83SPiotr Jasiukajtis leave 9825c28e83SPiotr Jasiukajtis ret 9925c28e83SPiotr Jasiukajtis 10025c28e83SPiotr Jasiukajtis.pow_main: 10125c28e83SPiotr Jasiukajtis / x ** 0 is 1 10225c28e83SPiotr Jasiukajtis movb %dl,%cl 10325c28e83SPiotr Jasiukajtis andb $0x45,%cl 10425c28e83SPiotr Jasiukajtis cmpb $0x40,%cl / C3=1 C2=0 C1=? C0=0 when +-0 10525c28e83SPiotr Jasiukajtis jne 1f 10625c28e83SPiotr Jasiukajtis fstp %st(0) / x 10725c28e83SPiotr Jasiukajtis fstp %st(0) / stack empty 10825c28e83SPiotr Jasiukajtis fld1 / 1 10925c28e83SPiotr Jasiukajtis ret 11025c28e83SPiotr Jasiukajtis 11125c28e83SPiotr Jasiukajtis1: / y is not zero 11225c28e83SPiotr Jasiukajtis PIC_G_LOAD(movzwl,__xpg6,eax) 11325c28e83SPiotr Jasiukajtis andl $_C99SUSv3_pow_treats_Inf_as_an_even_int,%eax 11425c28e83SPiotr Jasiukajtis cmpl $0,%eax 11525c28e83SPiotr Jasiukajtis je 1f 11625c28e83SPiotr Jasiukajtis 11725c28e83SPiotr Jasiukajtis / C99: 1 ** anything is 1 11825c28e83SPiotr Jasiukajtis fld1 / 1, y, x 11925c28e83SPiotr Jasiukajtis fucomp %st(2) / y, x 12025c28e83SPiotr Jasiukajtis fnstsw %ax / store status in %ax 12125c28e83SPiotr Jasiukajtis sahf / 80387 flags in %ax to 80386 flags 12225c28e83SPiotr Jasiukajtis jp 1f / so that pow(NaN1,NaN2) returns NaN2 12325c28e83SPiotr Jasiukajtis jne 1f 12425c28e83SPiotr Jasiukajtis fstp %st(0) / x 12525c28e83SPiotr Jasiukajtis ret 12625c28e83SPiotr Jasiukajtis 12725c28e83SPiotr Jasiukajtis1: 12825c28e83SPiotr Jasiukajtis / x ** NaN is NaN 12925c28e83SPiotr Jasiukajtis movb %dl,%cl 13025c28e83SPiotr Jasiukajtis andb $0x45,%cl 13125c28e83SPiotr Jasiukajtis cmpb $0x01,%cl / C3=0 C2=0 C1=? C0=1 when +-NaN 13225c28e83SPiotr Jasiukajtis jne 1f 13325c28e83SPiotr Jasiukajtis fstp %st(1) / y 13425c28e83SPiotr Jasiukajtis ret 13525c28e83SPiotr Jasiukajtis 13625c28e83SPiotr Jasiukajtis1: / y is not NaN 13725c28e83SPiotr Jasiukajtis / NaN ** y (except 0) is NaN 13825c28e83SPiotr Jasiukajtis movb %dh,%cl 13925c28e83SPiotr Jasiukajtis andb $0x45,%cl 14025c28e83SPiotr Jasiukajtis cmpb $0x01,%cl / C3=0 C2=0 C1=? C0=1 when +-NaN 14125c28e83SPiotr Jasiukajtis jne 1f 14225c28e83SPiotr Jasiukajtis fstp %st(0) / x 14325c28e83SPiotr Jasiukajtis ret 14425c28e83SPiotr Jasiukajtis 14525c28e83SPiotr Jasiukajtis1: / x is not NaN 14625c28e83SPiotr Jasiukajtis / x ** 1 is x 14725c28e83SPiotr Jasiukajtis fcoms PIC_L(one) / y , x 14825c28e83SPiotr Jasiukajtis fnstsw %ax / store status in %ax 14925c28e83SPiotr Jasiukajtis sahf / 80387 flags in %ax to 80386 flags 15025c28e83SPiotr Jasiukajtis jne 1f 15125c28e83SPiotr Jasiukajtis fstp %st(0) / x 15225c28e83SPiotr Jasiukajtis ret 15325c28e83SPiotr Jasiukajtis 15425c28e83SPiotr Jasiukajtis1: / y is not 1 15525c28e83SPiotr Jasiukajtis / +-(|x| > 1) ** +inf is +inf 15625c28e83SPiotr Jasiukajtis / +-(|x| > 1) ** -inf is +0 15725c28e83SPiotr Jasiukajtis / +-(|x| < 1) ** +inf is +0 15825c28e83SPiotr Jasiukajtis / +-(|x| < 1) ** -inf is +inf 15925c28e83SPiotr Jasiukajtis / +-(|x| = 1) ** +-inf is NaN 16025c28e83SPiotr Jasiukajtis movb %dl,%cl 16125c28e83SPiotr Jasiukajtis andb $0x47,%cl 16225c28e83SPiotr Jasiukajtis cmpb $0x05,%cl / C3=0 C2=1 C1=0 C0=1 when +inf 16325c28e83SPiotr Jasiukajtis je .yispinf 16425c28e83SPiotr Jasiukajtis cmpb $0x07,%cl / C3=0 C2=1 C1=1 C0=1 when -inf 16525c28e83SPiotr Jasiukajtis je .yisninf 16625c28e83SPiotr Jasiukajtis 16725c28e83SPiotr Jasiukajtis / +0 ** +y (except 0, NaN) is +0 16825c28e83SPiotr Jasiukajtis / -0 ** +y (except 0, NaN, odd int) is +0 16925c28e83SPiotr Jasiukajtis / +0 ** -y (except 0, NaN) is +inf (z flag) 17025c28e83SPiotr Jasiukajtis / -0 ** -y (except 0, NaN, odd int) is +inf (z flag) 17125c28e83SPiotr Jasiukajtis / -0 ** y (odd int) is - (+0 ** x) 17225c28e83SPiotr Jasiukajtis movb %dh,%cl 17325c28e83SPiotr Jasiukajtis andb $0x47,%cl 17425c28e83SPiotr Jasiukajtis cmpb $0x40,%cl / C3=1 C2=0 C1=0 C0=0 when +0 17525c28e83SPiotr Jasiukajtis je .xispzero 17625c28e83SPiotr Jasiukajtis cmpb $0x42,%cl / C3=1 C2=0 C1=1 C0=0 when -0 17725c28e83SPiotr Jasiukajtis je .xisnzero 17825c28e83SPiotr Jasiukajtis 17925c28e83SPiotr Jasiukajtis / +inf ** +y (except 0, NaN) is +inf 18025c28e83SPiotr Jasiukajtis / +inf ** -y (except 0, NaN) is +0 18125c28e83SPiotr Jasiukajtis / -inf ** +-y (except 0, NaN) is -0 ** -+y (NO z flag) 18225c28e83SPiotr Jasiukajtis movb %dh,%cl 18325c28e83SPiotr Jasiukajtis andb $0x47,%cl 18425c28e83SPiotr Jasiukajtis cmpb $0x05,%cl / C3=0 C2=1 C1=0 C0=1 when +inf 18525c28e83SPiotr Jasiukajtis je .xispinf 18625c28e83SPiotr Jasiukajtis cmpb $0x07,%cl / C3=0 C2=1 C1=1 C0=1 when -inf 18725c28e83SPiotr Jasiukajtis je .xisninf 18825c28e83SPiotr Jasiukajtis 18925c28e83SPiotr Jasiukajtis / x ** -1 is 1/x 19025c28e83SPiotr Jasiukajtis fcoms PIC_L(negone) / y , x 19125c28e83SPiotr Jasiukajtis fnstsw %ax / store status in %ax 19225c28e83SPiotr Jasiukajtis sahf / 80387 flags in %ax to 80386 flags 19325c28e83SPiotr Jasiukajtis jne 1f 19425c28e83SPiotr Jasiukajtis fld %st(1) / x , y , x 19525c28e83SPiotr Jasiukajtis fdivrs PIC_L(one) / 1/x , y , x 19625c28e83SPiotr Jasiukajtis jmp .signok / check for over/underflow 19725c28e83SPiotr Jasiukajtis 19825c28e83SPiotr Jasiukajtis1: / y is not -1 19925c28e83SPiotr Jasiukajtis / x ** 2 is x*x 20025c28e83SPiotr Jasiukajtis fcoms PIC_L(two) / y , x 20125c28e83SPiotr Jasiukajtis fnstsw %ax / store status in %ax 20225c28e83SPiotr Jasiukajtis sahf / 80387 flags in %ax to 80386 flags 20325c28e83SPiotr Jasiukajtis jne 1f 20425c28e83SPiotr Jasiukajtis fld %st(1) / x , y , x 20525c28e83SPiotr Jasiukajtis fld %st(0) / x , x , y , x 20625c28e83SPiotr Jasiukajtis fmulp / x^2 , y , x 20725c28e83SPiotr Jasiukajtis jmp .signok / check for over/underflow 20825c28e83SPiotr Jasiukajtis 20925c28e83SPiotr Jasiukajtis1: / y is not 2 21025c28e83SPiotr Jasiukajtis / x ** 1/2 is sqrt(x) 21125c28e83SPiotr Jasiukajtis fcoms PIC_L(half) / y , x 21225c28e83SPiotr Jasiukajtis fnstsw %ax / store status in %ax 21325c28e83SPiotr Jasiukajtis sahf / 80387 flags in %ax to 80386 flags 21425c28e83SPiotr Jasiukajtis jne 1f 21525c28e83SPiotr Jasiukajtis fld %st(1) / x , y , x 21625c28e83SPiotr Jasiukajtis fsqrt / sqrt(x) , y , x 21725c28e83SPiotr Jasiukajtis jmp .signok / check for over/underflow 21825c28e83SPiotr Jasiukajtis 21925c28e83SPiotr Jasiukajtis1: / y is not 1/2 22025c28e83SPiotr Jasiukajtis / make copies of x & y 22125c28e83SPiotr Jasiukajtis fld %st(1) / x , y , x 22225c28e83SPiotr Jasiukajtis fld %st(1) / y , x , y , x 22325c28e83SPiotr Jasiukajtis 22425c28e83SPiotr Jasiukajtis / -x ** y (an integer) is (-1)**(y) * (+x)**(y) 22525c28e83SPiotr Jasiukajtis / x ** y (x negative & y not integer) is NaN 22625c28e83SPiotr Jasiukajtis movl $0,%ecx / track whether to flip sign of result 22725c28e83SPiotr Jasiukajtis fld %st(1) / x , y , x , y , x 22825c28e83SPiotr Jasiukajtis ftst / compare %st(0) with 0 22925c28e83SPiotr Jasiukajtis fnstsw %ax / store status in %ax 23025c28e83SPiotr Jasiukajtis sahf / 80387 flags in %ax to 80386 flags 23125c28e83SPiotr Jasiukajtis fstp %st(0) / y , x , y , x 23225c28e83SPiotr Jasiukajtis ja .merge / x > 0 23325c28e83SPiotr Jasiukajtis / x < 0 23425c28e83SPiotr Jasiukajtis call .y_is_int 23525c28e83SPiotr Jasiukajtis cmpl $0,%ecx 23625c28e83SPiotr Jasiukajtis jne 1f 23725c28e83SPiotr Jasiukajtis / x < 0 & y != int so x**y = NaN (i flag) 23825c28e83SPiotr Jasiukajtis fstp %st(0) / x , y , x 23925c28e83SPiotr Jasiukajtis fstp %st(0) / y , x 24025c28e83SPiotr Jasiukajtis fstp %st(0) / x 24125c28e83SPiotr Jasiukajtis fstp %st(0) / stack empty 24225c28e83SPiotr Jasiukajtis fldz 24325c28e83SPiotr Jasiukajtis fdiv %st,%st(0) / 0/0 24425c28e83SPiotr Jasiukajtis ret 24525c28e83SPiotr Jasiukajtis 24625c28e83SPiotr Jasiukajtis1: / x < 0 & y = int 24725c28e83SPiotr Jasiukajtis fxch / x , y , y , x 24825c28e83SPiotr Jasiukajtis fchs / px = -x , y , y , x 24925c28e83SPiotr Jasiukajtis fxch / y , px , y , x 25025c28e83SPiotr Jasiukajtis.merge: 25125c28e83SPiotr Jasiukajtis / px > 0 25225c28e83SPiotr Jasiukajtis fxch / px , y , y , x 25325c28e83SPiotr Jasiukajtis 25425c28e83SPiotr Jasiukajtis / x**y = exp(y*ln(x)) 25525c28e83SPiotr Jasiukajtis fyl2x / t=y*log2(px) , y , x 25625c28e83SPiotr Jasiukajtis fld %st(0) / t , t , y , x 25725c28e83SPiotr Jasiukajtis frndint / [t] , t , y , x 25825c28e83SPiotr Jasiukajtis fxch / t , [t] , y , x 25925c28e83SPiotr Jasiukajtis fucom 26025c28e83SPiotr Jasiukajtis fnstsw %ax / store status in %ax 26125c28e83SPiotr Jasiukajtis sahf / 80387 flags in %ax to 80386 flags 26225c28e83SPiotr Jasiukajtis je 1f / t is integral 26325c28e83SPiotr Jasiukajtis fsub %st(1),%st / t-[t] , [t] , y , x 26425c28e83SPiotr Jasiukajtis f2xm1 / 2**(t-[t])-1 , [t] , y , x 26525c28e83SPiotr Jasiukajtis fadds PIC_L(one) / 2**(t-[t]) , [t] , y , x 26625c28e83SPiotr Jasiukajtis fscale / 2**t = px**y , [t] , y , x 26725c28e83SPiotr Jasiukajtis jmp 2f 26825c28e83SPiotr Jasiukajtis1: 26925c28e83SPiotr Jasiukajtis fstp %st(0) / t=[t] , y , x 27025c28e83SPiotr Jasiukajtis fld1 / 1 , t , y , x 27125c28e83SPiotr Jasiukajtis fscale / 1*2**t = x**y , t , y , x 27225c28e83SPiotr Jasiukajtis2: 27325c28e83SPiotr Jasiukajtis fstp %st(1) / x**y , y , x 27425c28e83SPiotr Jasiukajtis cmpl $1,%ecx 27525c28e83SPiotr Jasiukajtis jne .signok 27625c28e83SPiotr Jasiukajtis fchs / change sign since x<0 & y=-int 27725c28e83SPiotr Jasiukajtis.signok: 27825c28e83SPiotr Jasiukajtis fstp %st(2) / y , x**y 27925c28e83SPiotr Jasiukajtis fstp %st(0) / x**y 28025c28e83SPiotr Jasiukajtis ret 28125c28e83SPiotr Jasiukajtis 28225c28e83SPiotr Jasiukajtis/ ------------------------------------------------------------------------ 28325c28e83SPiotr Jasiukajtis 28425c28e83SPiotr Jasiukajtis.xispinf: 28525c28e83SPiotr Jasiukajtis ftst / compare %st(0) with 0 28625c28e83SPiotr Jasiukajtis fnstsw %ax / store status in %ax 28725c28e83SPiotr Jasiukajtis sahf / 80387 flags in %ax to 80386 flags 28825c28e83SPiotr Jasiukajtis ja .retpinf / y > 0 28925c28e83SPiotr Jasiukajtis jmp .retpzero / y < 0 29025c28e83SPiotr Jasiukajtis 29125c28e83SPiotr Jasiukajtis.xisninf: 29225c28e83SPiotr Jasiukajtis / -inf ** +-y is -0 ** -+y 29325c28e83SPiotr Jasiukajtis fchs / -y , x 29425c28e83SPiotr Jasiukajtis flds PIC_L(negzero) / -0 , -y , x 29525c28e83SPiotr Jasiukajtis fstp %st(2) / -y , -0 29625c28e83SPiotr Jasiukajtis jmp .xisnzero 29725c28e83SPiotr Jasiukajtis 29825c28e83SPiotr Jasiukajtis.yispinf: 29925c28e83SPiotr Jasiukajtis fld %st(1) / x , y , x 30025c28e83SPiotr Jasiukajtis fabs / |x| , y , x 30125c28e83SPiotr Jasiukajtis fcomps PIC_L(one) / y , x 30225c28e83SPiotr Jasiukajtis fnstsw %ax / store status in %ax 30325c28e83SPiotr Jasiukajtis sahf / 80387 flags in %ax to 80386 flags 30425c28e83SPiotr Jasiukajtis je .retponeorinvalid / x == -1 C99 30525c28e83SPiotr Jasiukajtis ja .retpinf / |x| > 1 30625c28e83SPiotr Jasiukajtis jmp .retpzero / |x| < 1 30725c28e83SPiotr Jasiukajtis 30825c28e83SPiotr Jasiukajtis.yisninf: 30925c28e83SPiotr Jasiukajtis fld %st(1) / x , y , x 31025c28e83SPiotr Jasiukajtis fabs / |x| , y , x 31125c28e83SPiotr Jasiukajtis fcomps PIC_L(one) / y , x 31225c28e83SPiotr Jasiukajtis fnstsw %ax / store status in %ax 31325c28e83SPiotr Jasiukajtis sahf / 80387 flags in %ax to 80386 flags 31425c28e83SPiotr Jasiukajtis je .retponeorinvalid / x == -1 C99 31525c28e83SPiotr Jasiukajtis ja .retpzero / |x| > 1 31625c28e83SPiotr Jasiukajtis jmp .retpinf / |x| < 1 31725c28e83SPiotr Jasiukajtis 31825c28e83SPiotr Jasiukajtis.xispzero: 31925c28e83SPiotr Jasiukajtis / y cannot be 0 or NaN ; stack has y , x 32025c28e83SPiotr Jasiukajtis ftst / compare %st(0) with 0 32125c28e83SPiotr Jasiukajtis fnstsw %ax / store status in %ax 32225c28e83SPiotr Jasiukajtis sahf / 80387 flags in %ax to 80386 flags 32325c28e83SPiotr Jasiukajtis ja .retpzero / y > 0 32425c28e83SPiotr Jasiukajtis / x = +0 & y < 0 so x**y = +inf 32525c28e83SPiotr Jasiukajtis jmp .retpinfzflag / ret +inf & z flag 32625c28e83SPiotr Jasiukajtis 32725c28e83SPiotr Jasiukajtis.xisnzero: 32825c28e83SPiotr Jasiukajtis / y cannot be 0 or NaN ; stack has y , x 32925c28e83SPiotr Jasiukajtis call .y_is_int 33025c28e83SPiotr Jasiukajtis cmpl $1,%ecx 33125c28e83SPiotr Jasiukajtis jne 1f / y is not an odd integer 33225c28e83SPiotr Jasiukajtis / y is an odd integer 33325c28e83SPiotr Jasiukajtis ftst / compare %st(0) with 0 33425c28e83SPiotr Jasiukajtis fnstsw %ax / store status in %ax 33525c28e83SPiotr Jasiukajtis sahf / 80387 flags in %ax to 80386 flags 33625c28e83SPiotr Jasiukajtis ja .retnzero / y > 0 33725c28e83SPiotr Jasiukajtis / x = -0 & y < 0 (odd int) return -inf (z flag) 33825c28e83SPiotr Jasiukajtis / x = -inf & y != 0 or NaN return -inf (NO z flag) 33925c28e83SPiotr Jasiukajtis movb %dh,%cl 34025c28e83SPiotr Jasiukajtis andb $0x45,%cl 34125c28e83SPiotr Jasiukajtis cmpb $0x05,%cl / C3=0 C2=1 C1=? C0=1 when +-inf 34225c28e83SPiotr Jasiukajtis je 2f 34325c28e83SPiotr Jasiukajtis fdiv %st,%st(1) / y / x, x (raise z flag) 34425c28e83SPiotr Jasiukajtis2: 34525c28e83SPiotr Jasiukajtis fstp %st(0) / x 34625c28e83SPiotr Jasiukajtis fstp %st(0) / stack empty 34725c28e83SPiotr Jasiukajtis flds PIC_L(ninfinity) / -inf 34825c28e83SPiotr Jasiukajtis ret 34925c28e83SPiotr Jasiukajtis 35025c28e83SPiotr Jasiukajtis1: / y is not an odd integer 35125c28e83SPiotr Jasiukajtis ftst / compare %st(0) with 0 35225c28e83SPiotr Jasiukajtis fnstsw %ax / store status in %ax 35325c28e83SPiotr Jasiukajtis sahf / 80387 flags in %ax to 80386 flags 35425c28e83SPiotr Jasiukajtis ja .retpzero / y > 0 35525c28e83SPiotr Jasiukajtis / x = -0 & y < 0 (not odd int) return +inf (z flag) 35625c28e83SPiotr Jasiukajtis / x = -inf & y not 0 or NaN return +inf (NO z flag) 35725c28e83SPiotr Jasiukajtis movb %dh,%cl 35825c28e83SPiotr Jasiukajtis andb $0x45,%cl 35925c28e83SPiotr Jasiukajtis cmpb $0x05,%cl / C3=0 C2=1 C1=? C0=1 when +-inf 36025c28e83SPiotr Jasiukajtis jne .retpinfzflag / ret +inf & divide-by-0 flag 36125c28e83SPiotr Jasiukajtis jmp .retpinf / return +inf (NO z flag) 36225c28e83SPiotr Jasiukajtis 36325c28e83SPiotr Jasiukajtis.retpzero: 36425c28e83SPiotr Jasiukajtis fstp %st(0) / x 36525c28e83SPiotr Jasiukajtis fstp %st(0) / stack empty 36625c28e83SPiotr Jasiukajtis fldz / +0 36725c28e83SPiotr Jasiukajtis ret 36825c28e83SPiotr Jasiukajtis 36925c28e83SPiotr Jasiukajtis.retnzero: 37025c28e83SPiotr Jasiukajtis fstp %st(0) / x 37125c28e83SPiotr Jasiukajtis fstp %st(0) / stack empty 37225c28e83SPiotr Jasiukajtis flds PIC_L(negzero) / -0 37325c28e83SPiotr Jasiukajtis ret 37425c28e83SPiotr Jasiukajtis 37525c28e83SPiotr Jasiukajtis.retponeorinvalid: 37625c28e83SPiotr Jasiukajtis PIC_G_LOAD(movzwl,__xpg6,eax) 37725c28e83SPiotr Jasiukajtis andl $_C99SUSv3_pow_treats_Inf_as_an_even_int,%eax 37825c28e83SPiotr Jasiukajtis cmpl $0,%eax 37925c28e83SPiotr Jasiukajtis je 1f 38025c28e83SPiotr Jasiukajtis fstp %st(0) / x 38125c28e83SPiotr Jasiukajtis fstp %st(0) / stack empty 38225c28e83SPiotr Jasiukajtis fld1 / 1 38325c28e83SPiotr Jasiukajtis ret 38425c28e83SPiotr Jasiukajtis 38525c28e83SPiotr Jasiukajtis1: 38625c28e83SPiotr Jasiukajtis fstp %st(0) / x 38725c28e83SPiotr Jasiukajtis fstp %st(0) / stack empty 38825c28e83SPiotr Jasiukajtis flds PIC_L(Snan) / Q NaN (i flag) 38925c28e83SPiotr Jasiukajtis fwait 39025c28e83SPiotr Jasiukajtis ret 39125c28e83SPiotr Jasiukajtis 39225c28e83SPiotr Jasiukajtis.retpinf: 39325c28e83SPiotr Jasiukajtis fstp %st(0) / x 39425c28e83SPiotr Jasiukajtis fstp %st(0) / stack empty 39525c28e83SPiotr Jasiukajtis flds PIC_L(pinfinity) / +inf 39625c28e83SPiotr Jasiukajtis ret 39725c28e83SPiotr Jasiukajtis 39825c28e83SPiotr Jasiukajtis.retpinfzflag: 39925c28e83SPiotr Jasiukajtis fstp %st(0) / x 40025c28e83SPiotr Jasiukajtis fstp %st(0) / stack empty 40125c28e83SPiotr Jasiukajtis fldz 40225c28e83SPiotr Jasiukajtis fdivrs PIC_L(one) / 1/0 40325c28e83SPiotr Jasiukajtis ret 40425c28e83SPiotr Jasiukajtis 40525c28e83SPiotr Jasiukajtis/ Set %ecx to 2 if y is an even integer, 1 if y is an odd integer, 40625c28e83SPiotr Jasiukajtis/ 0 otherwise. Assume y is not zero. Do not raise inexact or modify 40725c28e83SPiotr Jasiukajtis/ %edx. 40825c28e83SPiotr Jasiukajtis.y_is_int: 40925c28e83SPiotr Jasiukajtis movl 28(%ebp),%eax 41025c28e83SPiotr Jasiukajtis andl $0x7fff,%eax / exponent of y 41125c28e83SPiotr Jasiukajtis cmpl $0x403f,%eax 41225c28e83SPiotr Jasiukajtis jae 1f / |y| >= 2^64, an even int 41325c28e83SPiotr Jasiukajtis cmpl $0x3fff,%eax 41425c28e83SPiotr Jasiukajtis jb 2f / |y| < 1, can't be an int 41525c28e83SPiotr Jasiukajtis movl %eax,%ecx 41625c28e83SPiotr Jasiukajtis subl $0x403e,%ecx 41725c28e83SPiotr Jasiukajtis negl %ecx / 63 - unbiased exponent of y 41825c28e83SPiotr Jasiukajtis movl 20(%ebp),%eax 41925c28e83SPiotr Jasiukajtis bsfl %eax,%eax / index of least sig. 1 bit 42025c28e83SPiotr Jasiukajtis jne 3f / jump if 1 bit found 42125c28e83SPiotr Jasiukajtis movl 24(%ebp),%eax 42225c28e83SPiotr Jasiukajtis bsfl %eax,%eax 42325c28e83SPiotr Jasiukajtis addl $32,%eax / 32 + index of least sig. 1 bit 42425c28e83SPiotr Jasiukajtis3: 42525c28e83SPiotr Jasiukajtis cmpl %ecx,%eax 42625c28e83SPiotr Jasiukajtis jb 2f 42725c28e83SPiotr Jasiukajtis ja 1f 42825c28e83SPiotr Jasiukajtis movl $1,%ecx 42925c28e83SPiotr Jasiukajtis ret 43025c28e83SPiotr Jasiukajtis1: 43125c28e83SPiotr Jasiukajtis movl $2,%ecx 43225c28e83SPiotr Jasiukajtis ret 43325c28e83SPiotr Jasiukajtis2: 43425c28e83SPiotr Jasiukajtis xorl %ecx,%ecx 43525c28e83SPiotr Jasiukajtis ret 43625c28e83SPiotr Jasiukajtis .align 4 43725c28e83SPiotr Jasiukajtis SET_SIZE(powl) 438