Hello,
As far as I know 4.3 and 4.4 are no longer maintained and 4.3.6 and
4.4.7 were the last of their respective lines however if someone is kind
enough to look at the following, I would be extremely grateful. I found
a bug in 4.3.6 and 4.4.7 fixed in 4.5.0 but I am having a hard time
pinpointing the fix.
For the following code:
volatile unsigned int some_reg1;
volatile unsigned int some_reg2;
volatile unsigned int another_reg1;
volatile unsigned int another_reg2;
void poke_and_wait(int use_reg1)
{
volatile unsigned int *s_reg;
volatile unsigned int *a_reg;
if (use_reg1)
{
s_reg = &some_reg1;
a_reg = &another_reg1;
}
else
{
s_reg = &some_reg2;
a_reg = &another_reg2;
}
*s_reg = 0x1;
while (*a_reg & 0x2) ;
}
GCC 4.4.7 generates (4.3.6 generates equally incorrect code) with -Os:
poke_and_wait:
.LFB0:
.cfi_startproc
testl %edi, %edi
je .L2
movl another_reg1(%rip), %eax
movl $some_reg1, %edx
jmp .L3
.L2:
movl another_reg2(%rip), %eax
movl $some_reg2, %edx
.L3:
movl $1, (%rdx)
andl $2, %eax
.L4:
testl %eax, %eax
jne .L4
ret
.cfi_endproc
.LFE0:
.size poke_and_wait, .-poke_and_wait
The problem here is that *a_reg is not reloaded in the loop of .L4 ->
.L4 therefore being an infinite loop.
With GCC 4.5.0:
poke_and_wait:
.LFB0:
.cfi_startproc
testl %edi, %edi
movl $another_reg2, %eax
movl $another_reg1, %edx
cmove %rax, %rdx
movl $some_reg2, %ecx
movl $some_reg1, %eax
cmove %rcx, %rax
movl $1, (%rax)
.L3:
movl (%rdx), %eax
testb $2, %al
jne .L3
ret
.cfi_endproc
.LFE0:
.size poke_and_wait, .-poke_and_wait
Here is seems ok since (%rdx) is reloading the value.
I have been looking at the database but I can't pinpoint where this was
fixed. I am open to suggestion as to where this bug was fixed (revision,
date, file, ... anything helps).
Why?... I would like to port the fix back to 4.3.
Cheers,
--
PMatos