Hello! I have a problem with some inline assembly, which to me looks like a GCC bug but I first wanted to check that I haven't done any obvious mistake in my implementation. I see the problem both on MIPS and IA-32. The code I have is /* Assign 1 to v0 (the MIPS register used for passing function results) */ static inline int inline_asm(void) { register unsigned long __v0 asm("$2"); __asm__ volatile ( "li %0, 1\n" : "=r" (__v0) : : "memory" ); return (int) __v0; } void problem (void) { int a = inline_asm(); int b = overwriter(); tst(a, b); } When disassembling the generated code, this generates the following MIPS assembly code, with my comments 00000000 <problem>: 0: 27bdffe8 addiu sp,sp,-24 4: afbf0010 sw ra,16(sp) 8: 24020001 li v0,1 # Result of the inline assembly piece c: 0c000000 jal overwriter # Overwrites v0 10: 00000000 nop # jal delay slot - v0 should have been saved here! 14: 00402021 move a0,v0 # GCC thinks v0 still contains the result of the inline assembly 18: 0c000000 jal tst 1c: 00402821 move a1,v0 # ... *and* the result of overwriter()! 20: 8fbf0010 lw ra,16(sp) 24: 00000000 nop 28: 03e00008 jr ra 2c: 27bd0018 addiu sp,sp,24 This bug seems to be portable - I rewrote the inline assembly part for IA-32 - just a move to %eax - and %eax was indeed overwritten as well. The versions where I have this problem is mips-linux-gnu-gcc (GCC) 4.1.2 20061115 (prerelease) (Debian 4.1.1-21) gcc (GCC) 4.1.2 20061115 (prerelease) (Debian 4.1.1-21) but gcc-3.3 (IA-32) handles this just fine. So the usual question: Did I miss something in the inline assembly piece which can cause this problem or is this a proper GCC bug? (The problem was first manifested in some inline assembly for the Cibyl project, http://spel.bth.se/index.php/Cibyl, and the code is based on the Linux system calls for MIPS) -- // Simon
Attachment:
a.i
Description: Binary data