delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1997/01/30/01:25:36

From: korpela AT albert DOT ssl DOT berkeley DOT edu (Eric J. Korpela)
Newsgroups: comp.os.msdos.djgpp
Subject: Re: gcc inline assembly syntax
Date: 30 Jan 1997 01:50:04 GMT
Organization: Cal Berkeley-- Space Sciences Lab
Lines: 60
Message-ID: <5couoc$mfo@agate.berkeley.edu>
References: <01bc0ccf$cef8b2a0$80c4c7cd AT etu DOT planetweb>
NNTP-Posting-Host: albert.ssl.berkeley.edu
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp

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 -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019