Subject: Re: -O2 vax compiler bug?
To: Chuck Cranor <>
From: Matt Thomas <>
List: tech-toolchain
Date: 02/24/2002 14:42:27
At 11:46 AM 2/21/2002 -0800, Matt Thomas wrote:
>At 05:21 PM 9/10/2001 -0400, Chuck Cranor wrote:
>>     while attempting to compile a -current vax, i discovered
>>that the /bin/cp command no longer works.   i boiled it down
>>to the code segment included below.   it fails with both 1.5.2
>>and -current.
>>     can anyone fix it?   my vax needs a working /bin/cp.
>>the difference between the working -O version and the broken
>>-O2 version is:
>>vax[45]> diff utils-o.s utils-o2.s
>><       movab -96(fp),r0
>> >       movab -96(fp),r1
>><       tstl 56(r0)
>> >       movl 56(r1),r0
>><       tstl 52(r0)
>> >       movl 52(r1),r0
>><       cmpl 52(r0),$8388608
>> >       cmpl r0,$8388608
>>the problem is with changing the tstl's into movl's and the effect
>>on the condition codes.   the web pages below claim that tstl clears
>>both "C" and "V" condition codes, while "movl" clears "V" but
>>preserves "C"
>>it then uses blequ:
>>0x1846 <main+50>:       movl 52(r1),r0
>>0x184a <main+54>:       blequ 0x1866
>>says blequ tests both C and Z to determine if it should jump.
>>something is wrong with the handling of C.
>This turned out to be a 1 line fix in gcc/config/vax/vax.h.  However,
>until I do a complete build I'm not sure of the side effects, if any.
>RCS file: /cvsroot/gnusrc/gnu/dist/toolchain/gcc/config/vax/vax.h,v
>retrieving revision 1.8
>diff -u -r1.8 vax.h
>--- vax.h       2001/05/09 15:04:48     1.8
>+++ vax.h       2002/02/21 19:30:16
>@@ -904,7 +904,7 @@
>         CC_STATUS_INIT;                                         \
>        else if (GET_CODE (SET_DEST (EXP)) != ZERO_EXTRACT       \
>                && GET_CODE (SET_DEST (EXP)) != PC)              \
>-       { cc_status.flags = 0;                                  \
>+       { cc_status.flags = CC_NO_OVERFLOW;                     \
>           cc_status.value1 = SET_DEST (EXP);                    \
>           cc_status.value2 = SET_SRC (EXP); } }                 \
>    else if (GET_CODE (EXP) == PARALLEL                          \
>This tells final.c to ignore the C (even though it's called
>CC_NO_OVERFLOW) bit when generating is branches.  This causes
>your test program (and cp) to work correctly.

Actually, the above is both right and wrong.  Take a look at the
commit I did below (ignore the line about cmpdi).  I'll see if it
fixes the egcs problem as well (it should be easy to apply).

Modified Files:

         gnusrc/gnu/dist/toolchain/gcc/config/vax: vax.h

Log Message:

Fix long time codegen bug. Only the COMPARE, ADD, MINUS operations
actually set the C(arry) bit appropriately. All other leave it in an
indeterminate (to GCC) state. Mark that by setting CC_NO_OVERFLOW.
Change emission of branches that use the C bit to use
OUTPUT_JUMP so that if CC_NO_OVERFLOW is set, branches that would
normally use the C bit use opcodes that don't use the C bit (jgtru
-> jneq && jlssu -> jeql). Delete the cmpdi pattern.

>Matt Thomas               Internet:
>3am Software Foundry      WWW URL:
>Cupertino, CA             Disclaimer: I avow all knowledge of this message

Matt Thomas               Internet:
3am Software Foundry      WWW URL:
Cupertino, CA             Disclaimer: I avow all knowledge of this message