SQRT using FPU
- AlfaOmega08
- Member
- Posts: 226
- Joined: Wed Nov 07, 2007 12:15 pm
- Location: Italy
SQRT using FPU
Sometimes ago I found a small asm inline code for gcc.
I've unfortunately lost it.
I need it to "double sqrt(double x);"...
Does anyone know how to do it?
Else, I've to implement the Newton or Babilonian method :'(
Thanks in advance...
I've unfortunately lost it.
I need it to "double sqrt(double x);"...
Does anyone know how to do it?
Else, I've to implement the Newton or Babilonian method :'(
Thanks in advance...
- AlfaOmega08
- Member
- Posts: 226
- Joined: Wed Nov 07, 2007 12:15 pm
- Location: Italy
the linux kernel has a whole section in arch/i386/math-emu
but it looks complex as hell:
but it looks complex as hell:
Code: Select all
static void fsqrt_(FPU_REG *st0_ptr)
{
char st0_tag = st0_ptr->tag;
clear_C1();
if ( !(st0_tag ^ TW_Valid) )
{
int expon;
if (st0_ptr->sign == SIGN_NEG)
{
arith_invalid(st0_ptr); /* sqrt(negative) is invalid */
return;
}
#ifdef DENORM_OPERAND
if ( (st0_ptr->exp <= EXP_UNDER) && (denormal_operand()) )
return;
#endif DENORM_OPERAND
expon = st0_ptr->exp - EXP_BIAS;
st0_ptr->exp = EXP_BIAS + (expon & 1); /* make st(0) in [1.0 .. 4.0) */
wm_sqrt(st0_ptr, control_word); /* Do the computation */
st0_ptr->exp += expon >> 1;
st0_ptr->sign = SIGN_POS;
}
else if ( st0_tag == TW_Zero )
return;
else if ( st0_tag == TW_Infinity )
{
if ( st0_ptr->sign == SIGN_NEG )
arith_invalid(st0_ptr); /* sqrt(-Infinity) is invalid */
return;
}
else
{ single_arg_error(st0_ptr); return; }
}
glibc uses the following (public domain) code:
Code: Select all
double sqrt (double x)
{
double res;
asm ("fsqrt" : "=t" (res) : "0" (x));
return res;
}
- AlfaOmega08
- Member
- Posts: 226
- Joined: Wed Nov 07, 2007 12:15 pm
- Location: Italy