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