public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* Inline assembly question
@ 2004-03-10  5:26 Robert Rose
  2004-03-10 10:19 ` Ian Lance Taylor
  0 siblings, 1 reply; 2+ messages in thread
From: Robert Rose @ 2004-03-10  5:26 UTC (permalink / raw)
  To: gcc-help


Hi folks, I don't think there's anything quite as humbling as trying to 
do inline assembly inside a C program.. :)

I'm trying to do a few simple inline assembly instructions in a program 
I'm writing for the Symbian platform.  Symbian uses gcc version 
"2.9-psion-98r2" and compiles for the ARM platform.  I can insert 
"static" assembly statements fine without any issues, but when I try 
and uses extended assembly to refer to local variables I just can't 
figure things out.  For example, I would like to multiply two numbers 
together and store the result in another variable.  From what I've 
managed to scrap together from bits and pieces of online documentation, 
it appears this is done by:

static long mymul(long a, long b) {
   long result;
   __asm("mul %0,%1,%2" : "=r" (result) : "r" (a), "r" (b));
   return result;
}

When this is compiled it gives a warning almost everywhere (but not 
everywhere) I refer to this function.  When I run the code it crashes.  
The warning its giving me is:

"rd and rm should be different in mul".

What does that mean and how do I fix it? :-)  Thanks!

-robert

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Inline assembly question
  2004-03-10  5:26 Inline assembly question Robert Rose
@ 2004-03-10 10:19 ` Ian Lance Taylor
  0 siblings, 0 replies; 2+ messages in thread
From: Ian Lance Taylor @ 2004-03-10 10:19 UTC (permalink / raw)
  To: Robert Rose; +Cc: gcc-help

Robert Rose <rose@cafwap.net> writes:

> I'm trying to do a few simple inline assembly instructions in a
> program I'm writing for the Symbian platform.  Symbian uses gcc
> version "2.9-psion-98r2" and compiles for the ARM platform.  I can
> insert "static" assembly statements fine without any issues, but when
> I try and uses extended assembly to refer to local variables I just
> can't figure things out.  For example, I would like to multiply two
> numbers together and store the result in another variable.  From what
> I've managed to scrap together from bits and pieces of online
> documentation, it appears this is done by:
> 
> static long mymul(long a, long b) {
>    long result;
>    __asm("mul %0,%1,%2" : "=r" (result) : "r" (a), "r" (b));
>    return result;
> }
> 
> When this is compiled it gives a warning almost everywhere (but not
> everywhere) I refer to this function.  When I run the code it crashes.
> The warning its giving me is:
> 
> "rd and rm should be different in mul".
> 
> What does that mean and how do I fix it? :-)  Thanks!

The ARM mul instruction does not permit the result register to be the
same as the first operand.  That is,
    mul r0,r0,r1
is forbidden, but
    mul r0,r1,r0
is OK.

You got an error because gcc happened to put 'result' and 'a' into the
same register.  To avoid this, you have to prevent gcc from doing
that.  The easy way to prevent this is to mark the output operand as
an input/output operand, like this:
    __asm("mul %0,%1,%2" : "+r" (result) : "r" (a), "r" (b));
(that is, change '=' to '+' in the description of result).

That should prevent gcc from using the same register as an input
operand.  (It would actually be OK for gcc to use the same register
for the second operand, but that is harder to describe.)

Ian

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2004-03-10  4:01 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-03-10  5:26 Inline assembly question Robert Rose
2004-03-10 10:19 ` Ian Lance Taylor

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).