// float scalbnf( float x, int n )// float scalblnf( float x, long int n )// Returns x * 2^n computed efficiently, without undue over/underflow.
//
// -- Stephen Canon, January 2010
.text
.globl _scalblnf
.globl _scalbnf
.globl _ldexpf
#if defined __x86_64__
#define n %edi
#define ln %rdi
.align 4
_scalblnf:
cvtss2sd %xmm0, %xmm0 // (double)x
mov $300, %rdx
cmp %rdx, ln // if n > 300
cmovg %rdx, ln // n == 300
neg %rdx
cmp %rdx, ln // if n < -300
cmovl %rdx, ln // n == -300
jmp L_common
.align 4
_scalbnf:
_ldexpf:
cvtss2sd %xmm0, %xmm0 // (double)x
mov $300, %edx
cmp %edx, n // if n > 300
cmovg %edx, n // n == 300
neg %edx
cmp %edx, n // if n < -300
cmovl %edx, n // n == -300
L_common:
add $0x3ff, n //
shl $52, ln // (double)2^n
movd ln, %xmm1
mulsd %xmm1, %xmm0 // (double)(x * 2^n)
cvtsd2ss %xmm0, %xmm0 // x * 2^n
ret
#elif defined __i386__
#define n %eax
.align 4
_scalblnf:
_scalbnf:
_ldexpf:
cvtss2sd 4(%esp), %xmm0 // (double)x
mov 8(%esp), n
mov $300, %edx
cmp %edx, n // if n > 300
cmovg %edx, n // n == 300
neg %edx
cmp %edx, n // if n < -300
cmovl %edx, n // n == -300
add $0x3ff, n //
movd n, %xmm1
psllq $52, %xmm1 // (double)2^n
mulsd %xmm1, %xmm0 // (double)(x * 2^n)
cvtsd2ss %xmm0, %xmm0 // x * 2^n
movss %xmm0, 4(%esp)
flds 4(%esp)
ret
#else
#error "This implementation supports 32- and 64-bit Intel only"
#endif