Tag Archive for gcc inline result register problem

inline assembly woes – calling instructions

The following code below is a common problem experienced by developers who try and call an assembler instruction from C. Most online documentation would advise the following.
static long mymul(long a, long b) {
long result;
__asm(
“mul %0,%1,%2”
: “=r” (result)
: “r” (a), “r” (b));
return result;
}
This however givs the error.
“rd and rm should be different in mul”.
If one examines the assembler code they would see something like this
mul r0,r1,r0
gcc happens 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).
This will prevent gcc from using the same register as an input
operand.
The resulting assembler code will look like
mul r3, r1 ,r2
Note – Code samples from above where taken from a discussion on the gcc mailing list
http://gcc.gnu.org/ml/gcc-help/2004-03/msg00085.html