Mail Archives: djgpp/1997/01/30/01:25:36
In article <01bc0ccf$cef8b2a0$80c4c7cd AT etu DOT planetweb>,
Edgar Allan Tu <edgar AT key DOT com> wrote:
>Hi masters of gnu syntax,
>
>I'm new to doing inline assembly in gnu C. I'm try to do a code like this:
>#define FIXMUL(a,b) ( \
>{ \
> long _result; \
> asm ( \
> "imull %%ebx\n\t" \
> "shld $16,%%eax\n\t"); \
> __result; \
>}
>
> The only way I was able to do this was
>to do the following:
>#define FIXMUL(a, b) ( \
>{ \
long code deleted....
>})
First rule of inline assembly is "don't tell gcc what registers to use
unless you have to." In this case you I think you have to, so no problem
there. I prefer to tell it what registers to use in the parameter statements,
though. That way I don't also have to tell it the registers have been
clobbered.
You also made a couple of mistakes. "imul %ebx" is a 32x32=64 bit multiply.
If you use the expanding multiply you need to let GCC know that %edx gets
clobbered. You're also using the wrong form of shld for a 64 bit shift.
And I'm also pretty sure you want a right shift to renormalize.
Here's how I would write your macro if I were to use inline assembly.
inline long static FIXMUL(long a, long b)
{
long result;
asm ( "
imull %2
shrdl $16,%%edx,%0
"
: "=a" (result) /* result comes out of eax register */
: "0" (a), "g" (b) /* a goes into eax, use any convenient
form of b */
: "edx"); /* edx gets clobbered */
return (result);
}
If GCC's long long math routines were better I'd just tell you to use
#define fixmul(a,b) ((long)(((long long)(a)*(b))>>16))
but GCC doesn't seem to do too well with 64 bit stuff on x86.
(BTW this is the zeroth rule of inline assembly: don't use it unless
you have to.)
Eric
--
Eric Korpela | An object at rest can never be
korpela AT ssl DOT berkeley DOT edu | stopped.
<a href="http://www.cs.indiana.edu/finger/mofo.ssl.berkeley.edu/korpela/w">
Click here for more info.</a>
- Raw text -