pace@PREP.AI.MIT.EDU (Pace Willison) (02/04/89)
I think I've tracked down a bug where the condition codes
are not maintained properly. I'll give a quick summary now,
then more tomorrow after I can work on it some more. If you
see that I'm lost, please tell me before I waste too much time.
I'm using gcc 1.33 compiled with itself on a system 5 80386, using
COFF_ENCAPSULATE.
CC_REVERSED is set in i386.md for some instructions, but is cleared
only by CC_STATUS_INIT. It should also be cleared by some of the
instructions that don't set it. In the code below, I think that
CC_REVERSED gets set at point [2], but since none of the intervining
instructions do CC_STATUS_INIT, it is still set at [3]. [3] ought to
clear CC_REVERSED, and since it doesn't the following jump instruction
thinks it needs to be reversed.
The fix is to put "cc_status.flags &= ~CC_REVERSED" in several of
the i386.md templates. I'll begin learning how to do that tomorrow...
(I expect it will involve comparing notice_update_cc() with i386.md.)
It's amazing that the compiler apparently successfully compiles itself,
all of the binutils, gas, and emacs. The bug has only shown up in
uncompress when the input is a file (but not if it is the standard input.)
Pace
struct foo {
int x;
char *y;
};
struct foo i;
unsigned char a;
main()
{
/* the original code was checking the magic number at the beginnin
* of the file:
* if (getchar () != a || getchar () != b) continue;
*/
for (;;) {
if ((--i.x < 0 ? foo() : i.x) != a)
return;
if ((--i.x < 0 ? foo() : i.x) != a)
return;
}
}
.file "x.c"
gcc_compiled.:
.text
.align 2
.globl _main
_main:
pushl %ebp
movl %esp,%ebp
pushl %ebx
movl $_i,%ebx
L2:
decl (%ebx) [1]<----- first decrement
jns L6
call _foo
movl %eax,%edx
jmp L7
L6:
movl (%ebx),%edx
L7:
movzbl _a,%eax
cmpl %edx,%eax [2]<--- CC_REVERSED set here
jne L1
decl (%ebx) [3]<---- second decrement, CC_REVERSED accidentally
left on
cmpl $0,(%ebx) <- compare needlessly inserted
jle L9 <- jump sense reversed
call _foo
movl %eax,%edx
jmp L10
L9:
movl (%ebx),%edx
L10:
movzbl _a,%eax
cmpl %edx,%eax
je L2
L1:
leal -4(%ebp),%esp
popl %ebx
leave
ret
.comm _a,1
.comm _i,8