Dear all,
I would appreciate any help in spotting what might be wrong in the
code snippet (attached at the end). A little bit of background: for
reasons not particularly relevant here, I cannot use C math library as
it is, so I have to supply my own implementation of a few math
functions that are used in my code. I searched around and eventually
enclose the following code in my C program (taken from the dietlibc
code base, with some change). The goal is to replace calls to 'log/
pow' with my version 'my_log/my_pow'.
It's working to some extent. For example the following code:
>>>
printf("%.3f\n", my_pow(2.0, 35.3));
//... some other code
printf("%.3f\n", my_pow(2.0, 35.3));
<<<
outputs:
42301799935.756
2.000
In other words, the first invocation get the right results, but not
the second one. My intuition is that both log and pow are pure
function, so this should not happen. But then again, I have limited
experience in FP coding at assembly level, so there might be some
thing I overlooked. Like maybe the special ways the FP registers or
FP status register have to be manipulated.
Thanks ahead for any comments.
-bx
Begin code snippet:
======================
double my_log(double);
double my_pow(double x, double y);
asm(".text\n"
".global my_log,my_pow,__finexp\n"
".type my_log,@[EMAIL PROTECTED]
"
".type my_pow,@[EMAIL PROTECTED]
"
".type __finexp,@[EMAIL PROTECTED]
"
"my_log:\n"
"fldln2\n"
"fldl 4(%esp)\n"
"fyl2x\n"
"ret\n"
#ifndef __DYN_LIB
"__finexp:\n"
#endif
".Lfinexp:\n"
"fst %st(1)\n"
"frndint\n"
"fst %st(2)\n"
"fsubrp\n"
"f2xm1\n"
"fld1\n"
"faddp\n"
"fscale\n"
"ret\n"
#ifdef __DYN_LIB
"__finexp:\n"
"PIC_RESTORE\n"
"jmp .Lfinexp\n"
#endif
"my_pow:\n"
"fldl 4(%esp)\n"
"fldl 12(%esp)\n"
".L__pow:\n"
"ftst\n"
"fstsw %ax\n"
"fld1\n"
"sahf\n"
"jz 1f\n"
"fcomp %st(1)\n"
"fstsw %ax\n"
"fxch\n"
"sahf\n"
"jz 1f\n"
"ftst\n"
"fstsw %ax\n"
"sahf\n"
"jz 1f\n"
"jnc .Lfinpow\n"
"fxch\n"
"fld %st(0)\n"
"frndint\n"
"fcomp %st(1)\n"
"fstsw %ax\n"
"fxch\n"
"sahf\n"
"jnz .Lfinpow\n"
"fld1\n"
"fadd %st(0)\n"
"fdivr %st(2),%st(0)\n"
"frndint\n"
"fadd %st(0),%st(0)\n"
"fcomp %st(2)\n"
"fstsw %ax\n"
"fchs\n"
"sahf\n"
"jz .Lfinpow\n"
"call .Lfinpow\n"
"fchs\n"
"1: ret\n"
".Lfinpow:\n"
"fyl2x\n"
#ifdef __DYN_LIB
"PIC_SAVE\n"
"PIC_INIT\n"
"jmp __finexp@[EMAIL PROTECTED]
"
#else
"jmp __finexp\n"
#endif
".Lende:\n"
".size my_log,.Lende-my_log\n"
".size my_pow,.Lende-my_pow\n"
".size __finexp,.Lende-__finexp\n"
);
======================
End code snippet.


|