s_ilogb.s   [plain text]


/*
 * Written by Ian Ollmann
 *
 * Copyright © 2005, Apple Computer. All rights reserved.
 */

#include <machine/asm.h>

#define LOCAL_STACK_SIZE		4
#include "abi.h"


ENTRY(ilogbl)
    SUBP        $LOCAL_STACK_SIZE,  STACKP
	movl		$0x4f000000, (STACKP)           //  0x1.0p31
    flds        (STACKP)                        //  { 0x1.0p31 }
	fldt		FIRST_ARG_OFFSET(STACKP)        //	{ x, 0x1.0p31 }
	fldz										//	{ 0, x, 0x1.0p31 }
	fucomip		%st(1), %st(0)					//	{ x, 0x1.0p31 }							if( x == 0 or NaN )
	fcmove		%st(1), %st(0)					//	{ x or 0x1.0p31, 0x1.0p31 }				then x = 0x1.0p31			//avoids div/0 for fxtract(0)
	fxtract										//	{ sig, exp, 0x1.0p31 }
	fstp		%st(0)							//	{ exp, 0x1.0p31 }
	fcmove		%st(1), %st(0)					//	{ exp or 0x1.0p31, 0x1.0p31 }		if( x == 0 or NaN )	then exp = 0x1.0p31		//set to overflow
    movl        $0x7fffffff,    %edx            //  load the inf result 
    fucomi      %st(1), %st(0)                  //  compare exp with 0x1.0p31. Only inf inputs will have exponents that test > 0x1.0p31.
    fistpl      (STACKP)                        //  convert exponent to int. Set invalid if input was zero, NaN or Inf
    fstp        %st(0)                          //  { }
    movl        (STACKP),   %eax                //  load result into eax
    cmova       %edx,       %eax                //  patch up Inf result to return 0x7fffffff instead
    ADDP        $LOCAL_STACK_SIZE,  STACKP
    ret