[Bug middle-end/46164] New: Local variables in specified registers don't work correctly with inline asm operands
siarhei.siamashka at gmail dot com
gcc-bugzilla@gcc.gnu.org
Mon Oct 25 10:13:00 GMT 2010
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46164
Summary: Local variables in specified registers don't work
correctly with inline asm operands
Product: gcc
Version: 4.5.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: middle-end
AssignedTo: unassigned@gcc.gnu.org
ReportedBy: siarhei.siamashka@gmail.com
When testing with gcc 4.5.1
==== ARM ====
$ cat test.c
int f(int a)
{
register int result asm("r0");
asm (
"add r0, %[a], #123\n"
: [result] "=&r" (result)
: [a] "r" (a)
);
return result;
}
$ gcc -O2 -c test.c
$ objdump -d test.o
00000000 <f>:
0: e280007b add r0, r0, #123 ; 0x7b
4: e1a00003 mov r0, r3
8: e12fff1e bx lr
Here the local variable 'result' gets assigned to register r3 instead of r0
causing all kind of problems.
==== x86-64 ====
$ cat test.c
int f(int a)
{
register int result asm("edi");
asm (
"lea 0x7b(%[a]), %%edi\n"
: [result] "=&r" (result)
: [a] "r" (a)
);
return result;
}
$ gcc -O2 -c test.c
$ objdump -d test.o
0000000000000000 <f>:
0: 67 8d 7f 7b addr32 lea 0x7b(%edi),%edi
4: c3 retq
=================================
And some final bits.
http://gcc.gnu.org/onlinedocs/gcc/Local-Reg-Vars.html#Local-Reg-Vars
http://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html
The documantation is a bit confusing, but it gives at least one example of
assigining variables to specified registers:
"Sometimes you need to make an asm operand be a specific register, but there's
no matching constraint letter for that register by itself. To force the operand
into that register, use a local variable for the operand and specify the
register in the variable declaration. See Explicit Reg Vars. Then for the asm
operand, use any register constraint letter that matches the register:
register int *p1 asm ("r0") = ...;
register int *p2 asm ("r1") = ...;
register int *result asm ("r0");
asm ("sysint" : "=r" (result) : "0" (p1), "r" (p2));"
Let's try to use something like that with x86-64:
/********************/
void abort();
int __attribute__((noinline)) f(int a)
{
register int p1 asm ("edi");
register int result asm ("edi");
asm (
"mov %2, %0\n"
"add %2, %0\n"
"add %2, %0\n"
: "=r" (result) : "0" (p1), "r" (a));
return result;
}
int main()
{
if (f(1) != 3)
abort();
}
/********************/
This testcase fails.
So is it a bug in gcc? Or the documentation is wrong? Or I'm missing something?
More information about the Gcc-bugs
mailing list