[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Help with Hand-Optimized Assembly
From: |
Bill Woessner |
Subject: |
Help with Hand-Optimized Assembly |
Date: |
Wed, 28 Mar 2012 18:29:54 -0000 |
User-agent: |
G2/1.0 |
I'm a 100% total newbie at writing assembly. But I figured it would
be a good exercise. And besides, this tiny chunk of code is
definitely in the critical path of something I'm working on. Any and
all advice would be appreciated.
I'm trying to rewrite the following function in x86 assembly:
inline double DiffAngle(double theta1, double theta2)
{
double delta(theta1 - theta2);
return std::abs(delta) <= M_PI ? delta : delta - copysign(2 * M_PI,
delta);
}
To my great surprise, I've actually been somewhat successful. Here's
what I have so far:
double DiffAngle(double theta1, double theta2)
{
asm(
"fldl 4(%esp);"
"fsubl 12(%esp);"
"fxam;"
"fnstsw %ax;"
"fldl TWO_PI;"
"testb $2, %ah;"
"fldl NEG_TWO_PI;"
"fcmovne %st(1), %st;"
"fstp %st(1);"
"fsubr %st(1), %st;"
"fldpi;"
"fld %st(2);"
"fabs;"
"fcomip %st(1), %st;"
"fstp %st(0);"
"fcmovbe %st(1), %st;"
"fstp %st(1);"
"rep;"
"ret;"
"NEG_TWO_PI:;"
".long 1413754136;"
".long 1075388923;"
"TWO_PI:;"
".long 1413754136;"
".long -1072094725;"
);
}
This compiles, runs and produces the correct answers. But I have a
few issues with it:
1) If I declare this function inline, it gives me garbage (like
10^-304)
2) If I compile with -Wall, I get a warning that the function doesn't
return a value, which is absolutely true, but I don't know how to fix
it.
3) I don't like how TWO_PI and NEG_TWO_PI are defined. I had to steal
it from some generated assembly. It would be nice to use M_PI,
4*atan(1) or something like that.
Thanks in advance,
Bill