Blame sysdeps/i386/fpu/s_cbrtf.S

Packit Service 82fcde
/* Compute cubic root of float value.
Packit Service 82fcde
   Copyright (C) 1997-2018 Free Software Foundation, Inc.
Packit Service 82fcde
   This file is part of the GNU C Library.
Packit Service 82fcde
   Contributed by Dirk Alboth <dirka@uni-paderborn.de> and
Packit Service 82fcde
   Ulrich Drepper <drepper@cygnus.com>, 1997.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is free software; you can redistribute it and/or
Packit Service 82fcde
   modify it under the terms of the GNU Lesser General Public
Packit Service 82fcde
   License as published by the Free Software Foundation; either
Packit Service 82fcde
   version 2.1 of the License, or (at your option) any later version.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is distributed in the hope that it will be useful,
Packit Service 82fcde
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 82fcde
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 82fcde
   Lesser General Public License for more details.
Packit Service 82fcde
Packit Service 82fcde
   You should have received a copy of the GNU Lesser General Public
Packit Service 82fcde
   License along with the GNU C Library; if not, see
Packit Service 82fcde
   <http://www.gnu.org/licenses/>.  */
Packit Service 82fcde
Packit Service 82fcde
#include <machine/asm.h>
Packit Service 82fcde
#include <libm-alias-float.h>
Packit Service 82fcde
Packit Service 82fcde
        .section .rodata
Packit Service 82fcde
Packit Service 82fcde
        .align ALIGNARG(4)
Packit Service 82fcde
        .type f3,@object
Packit Service 82fcde
f3:	.double 0.191502161678719066
Packit Service 82fcde
        ASM_SIZE_DIRECTIVE(f3)
Packit Service 82fcde
        .type f2,@object
Packit Service 82fcde
f2:	.double 0.697570460207922770
Packit Service 82fcde
        ASM_SIZE_DIRECTIVE(f2)
Packit Service 82fcde
        .type f1,@object
Packit Service 82fcde
f1:	.double 0.492659620528969547
Packit Service 82fcde
        ASM_SIZE_DIRECTIVE(f1)
Packit Service 82fcde
Packit Service 82fcde
#define CBRT2		1.2599210498948731648
Packit Service 82fcde
#define ONE_CBRT2	0.793700525984099737355196796584
Packit Service 82fcde
#define SQR_CBRT2	1.5874010519681994748
Packit Service 82fcde
#define ONE_SQR_CBRT2	0.629960524947436582364439673883
Packit Service 82fcde
Packit Service 82fcde
	.type factor,@object
Packit Service 82fcde
        .align ALIGNARG(4)
Packit Service 82fcde
factor:	.double ONE_SQR_CBRT2
Packit Service 82fcde
	.double ONE_CBRT2
Packit Service 82fcde
	.double 1.0
Packit Service 82fcde
	.double CBRT2
Packit Service 82fcde
	.double SQR_CBRT2
Packit Service 82fcde
	ASM_SIZE_DIRECTIVE(factor)
Packit Service 82fcde
Packit Service 82fcde
        .type two25,@object
Packit Service 82fcde
two25:	.byte 0, 0, 0, 0x4c
Packit Service 82fcde
        ASM_SIZE_DIRECTIVE(two25)
Packit Service 82fcde
Packit Service 82fcde
#ifdef PIC
Packit Service 82fcde
#define MO(op) op##@GOTOFF(%ebx)
Packit Service 82fcde
#define MOX(op,x) op##@GOTOFF(%ebx,x,1)
Packit Service 82fcde
#else
Packit Service 82fcde
#define MO(op) op
Packit Service 82fcde
#define MOX(op,x) op(x)
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
	.text
Packit Service 82fcde
ENTRY(__cbrtf)
Packit Service 82fcde
	movl	4(%esp), %eax
Packit Service 82fcde
	xorl	%ecx, %ecx
Packit Service 82fcde
	movl	%eax, %edx
Packit Service 82fcde
	andl	$0x7fffffff, %eax
Packit Service 82fcde
	jz	1f
Packit Service 82fcde
	cmpl	$0x7f800000, %eax
Packit Service 82fcde
	jae	1f
Packit Service 82fcde
Packit Service 82fcde
#ifdef PIC
Packit Service 82fcde
	pushl	%ebx
Packit Service 82fcde
	cfi_adjust_cfa_offset (4)
Packit Service 82fcde
	cfi_rel_offset (ebx, 0)
Packit Service 82fcde
	LOAD_PIC_REG (bx)
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
	cmpl	$0x00800000, %eax
Packit Service 82fcde
	jae	2f
Packit Service 82fcde
Packit Service 82fcde
#ifdef PIC
Packit Service 82fcde
	flds	8(%esp)
Packit Service 82fcde
#else
Packit Service 82fcde
	flds	4(%esp)
Packit Service 82fcde
#endif
Packit Service 82fcde
	fmuls	MO(two25)
Packit Service 82fcde
	movl	$-25, %ecx
Packit Service 82fcde
#ifdef PIC
Packit Service 82fcde
	fstps	8(%esp)
Packit Service 82fcde
	movl	8(%esp), %eax
Packit Service 82fcde
#else
Packit Service 82fcde
	fstps	4(%esp)
Packit Service 82fcde
	movl	4(%esp), %eax
Packit Service 82fcde
#endif
Packit Service 82fcde
	movl	%eax, %edx
Packit Service 82fcde
	andl	$0x7fffffff, %eax
Packit Service 82fcde
Packit Service 82fcde
2:	shrl	$23, %eax
Packit Service 82fcde
	andl	$0x807fffff, %edx
Packit Service 82fcde
	subl	$126, %eax
Packit Service 82fcde
	orl	$0x3f000000, %edx
Packit Service 82fcde
	addl	%eax, %ecx
Packit Service 82fcde
#ifdef PIC
Packit Service 82fcde
	movl	%edx, 8(%esp)
Packit Service 82fcde
Packit Service 82fcde
	flds	8(%esp)			/* xm */
Packit Service 82fcde
#else
Packit Service 82fcde
	movl	%edx, 4(%esp)
Packit Service 82fcde
Packit Service 82fcde
	flds	4(%esp)			/* xm */
Packit Service 82fcde
#endif
Packit Service 82fcde
	fabs
Packit Service 82fcde
Packit Service 82fcde
	/* The following code has two tracks:
Packit Service 82fcde
	    a) compute the normalized cbrt value
Packit Service 82fcde
	    b) compute xe/3 and xe%3
Packit Service 82fcde
	   The right track computes the value for b) and this is done
Packit Service 82fcde
	   in an optimized way by avoiding division.
Packit Service 82fcde
Packit Service 82fcde
	   But why two tracks at all?  Very easy: efficiency.  Some FP
Packit Service 82fcde
	   instruction can overlap with a certain amount of integer (and
Packit Service 82fcde
	   FP) instructions.  So we get (except for the imull) all
Packit Service 82fcde
	   instructions for free.  */
Packit Service 82fcde
Packit Service 82fcde
	fld	%st(0)			/* xm : xm */
Packit Service 82fcde
	fmull	MO(f3)			/* f3*xm : xm */
Packit Service 82fcde
			movl	$1431655766, %eax
Packit Service 82fcde
	fsubrl	MO(f2)			/* f2-f3*xm : xm */
Packit Service 82fcde
			imull	%ecx
Packit Service 82fcde
	fmul	%st(1)			/* (f2-f3*xm)*xm : xm */
Packit Service 82fcde
			movl	%ecx, %eax
Packit Service 82fcde
	faddl	MO(f1)			/* u:=f1+(f2-f3*xm)*xm : xm */
Packit Service 82fcde
			sarl	$31, %eax
Packit Service 82fcde
	fld	%st			/* u : u : xm */
Packit Service 82fcde
			subl	%eax, %edx
Packit Service 82fcde
	fmul	%st(1)			/* u*u : u : xm */
Packit Service 82fcde
	fld	%st(2)			/* xm : u*u : u : xm */
Packit Service 82fcde
	fadd	%st			/* 2*xm : u*u : u : xm */
Packit Service 82fcde
	fxch	%st(1)			/* u*u : 2*xm : u : xm */
Packit Service 82fcde
	fmul	%st(2)			/* t2:=u*u*u : 2*xm : u : xm */
Packit Service 82fcde
			movl	%edx, %eax
Packit Service 82fcde
	fadd	%st, %st(1)		/* t2 : t2+2*xm : u : xm */
Packit Service 82fcde
			leal	(%edx,%edx,2),%edx
Packit Service 82fcde
	fadd	%st(0)			/* 2*t2 : t2+2*xm : u : xm */
Packit Service 82fcde
			subl	%edx, %ecx
Packit Service 82fcde
	faddp	%st, %st(3)		/* t2+2*xm : u : 2*t2+xm */
Packit Service 82fcde
			shll	$3, %ecx
Packit Service 82fcde
	fmulp				/* u*(t2+2*xm) : 2*t2+xm */
Packit Service 82fcde
	fdivp	%st, %st(1)		/* u*(t2+2*xm)/(2*t2+xm) */
Packit Service 82fcde
	fmull	MOX(16+factor,%ecx)	/* u*(t2+2*xm)/(2*t2+xm)*FACT */
Packit Service 82fcde
	pushl	%eax
Packit Service 82fcde
	cfi_adjust_cfa_offset (4)
Packit Service 82fcde
	fildl	(%esp)			/* xe/3 : u*(t2+2*xm)/(2*t2+xm)*FACT */
Packit Service 82fcde
	fxch				/* u*(t2+2*xm)/(2*t2+xm)*FACT : xe/3 */
Packit Service 82fcde
	fscale				/* u*(t2+2*xm)/(2*t2+xm)*FACT*2^xe/3 */
Packit Service 82fcde
	popl	%edx
Packit Service 82fcde
	cfi_adjust_cfa_offset (-4)
Packit Service 82fcde
#ifdef PIC
Packit Service 82fcde
	movl	8(%esp), %eax
Packit Service 82fcde
	popl	%ebx
Packit Service 82fcde
	cfi_adjust_cfa_offset (-4)
Packit Service 82fcde
	cfi_restore (ebx)
Packit Service 82fcde
#else
Packit Service 82fcde
	movl	4(%esp), %eax
Packit Service 82fcde
#endif
Packit Service 82fcde
	testl	%eax, %eax
Packit Service 82fcde
	fstp	%st(1)
Packit Service 82fcde
	jns	4f
Packit Service 82fcde
	fchs
Packit Service 82fcde
4:	ret
Packit Service 82fcde
Packit Service 82fcde
	/* Return the argument.  */
Packit Service 82fcde
1:	flds	4(%esp)
Packit Service 82fcde
	ret
Packit Service 82fcde
END(__cbrtf)
Packit Service 82fcde
libm_alias_float (__cbrt, cbrt)