[Bug inline-asm/37895] New: AVR inline assembly clobbers input value
Rudolf dot Leitgeb at gmx dot at
gcc-bugzilla@gcc.gnu.org
Wed Oct 22 21:21:00 GMT 2008
I carefully followed the instructions how to write proper inline assembly for
avr-gcc, however, the resulting code didn't work. I tracked down the problem
and came to the conclusion that gcc assigned wrong registers to the output
variable and therefore corrupted my input data.
Here's sample code, I tried to write a fast routine for multiplying a 16-bit
number with an 8 bit number, the result would be written to a 32 bit number:
static inline int32_t mul_16_8(uint16_t left, uint8_t right) {
int32_t result;
asm volatile(
"clr %C0;" "\n\t"
"clr %D0;" "\n\t"
"mul %A1, %2;" "\n\t"
"movw %A0, r0;" "\n\t"
"mul %B1, %2;" "\n\t"
"add %B0, r0;" "\n\t"
"adc %C0, r1;" "\n\t"
"clr __zero_reg__" "\n\t"
:"=&r" (result)
:"r" (left),"r" (right)
:"r0", "r1"
);
return result;
}
If I invoke this function from regular C code, such as
int32_t res = mul_16_8(0x1234, 0x56);
I get incorrect results. I believe this is the case because the "left" variable
is assigned to the same registers as "result", and "left" is overwritten during
the multiplication. According to several web pages the "=&r" (result)
directive should prevent exactly this ....
Since the bug reporting guide explicitly discourages from posting assembly code
generated by the compiler, I refrain from posting it here, although it might
help clarify this issue. I will post it upon request, though :)
Some extra information:
I don't use plain vanilla avr gcc, but the win avr version: WinAVR 20071221,
which is 4.2.2 plus some AVR specific patches (some bug fixes, extra device
support). Please let me know, if gcc-bugzilla is the wrong address for these
bugs!
--
Summary: AVR inline assembly clobbers input value
Product: gcc
Version: 4.2.2
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: inline-asm
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: Rudolf dot Leitgeb at gmx dot at
GCC build triplet: i686-unknown-linux
GCC host triplet: i686-unknown-linux
GCC target triplet: avr
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37895
More information about the Gcc-bugs
mailing list