[gnu.gcc.bug] Incorrect assembler output by implicit conversion to long long.

schoenfr%tubsibr@UUNET.UU.NET (Erik Schoenfelder) (11/21/89)

Hi!

System: Sun 3/60; SunOS 4.0.3_EXPORT; GNU CC v1.36 (config.gcc sun3-os4);


The problem is about the conversion of a constant to a long long value
in expressions (e.g. long_long_a = long_long_a - 1; ), when the
constant is negative, or the operator is a ``-''.


I think, that the value of -1 (may be every neagtive value) is
sometimes not correctly converted to a long long value, although this
should happen automatically.


In the following example, every of the expressions will be evaluated
with a call of _adddi3 from gnulib2; one of the parameters is set to
-1, the other to the value of a (see below).
In this parameters, the negative constant has sometimes cleared half
of its bits.


The example: 


% cat aa.c

long long a;

foo()
{
	a = a - 1;			/* bad long long -1 */
	a = -1 + a;			/* good long long -1 */
	a = a - (long long) 1;		/* bad long long -1 */
	a = a + (long long) -1;		/* good long long -1 */
/*	a -= 1;				/* also bad. */
/*	a += -1;			/* also good. */
}
% 
% gcc -v -S aa.c
gcc version 1.36
 /usr/local/lib/gcc-cpp -v -undef -D__GNUC__ -Dmc68000 -Dsun -Dunix -D__mc68000__ -D__sun__ -D__unix__ -D__HAVE_68881__ -Dmc68020 aa.c /usr/tmp/cca15867.cpp
GNU CPP version 1.36
 /usr/local/lib/gcc-cc1 /usr/tmp/cca15867.cpp -quiet -dumpbase aa.c -version -o aa.s
GNU C version 1.36 (68k, MIT syntax) compiled by GNU C version 1.36.
default target switches: -m68020 -mc68020 -m68881 -mbitfield
% 
% cat aa.s
#NO_APP
gcc_compiled.:
.text
	.even
.globl _foo
_foo:
	link a6,#0
	moveml #0x3000,sp@-
	movel #___adddi3,d0
	movel #-1,d2				***** a = a - 1;
	clrl d3					***** 
	movel d3,sp@-
	movel d2,sp@-
	movel _a+4,sp@-
	movel _a,sp@-
	jbsr ___adddi3
[ lines discarded ...]
	movel #___adddi3,d0
	movel #-1,sp@-				***** a = -1 + a;
	movel #-1,sp@-				***** 
	movel _a+4,sp@-
	movel _a,sp@-
	jbsr ___adddi3
[ lines discarded ...]
	movel #___adddi3,d0
	movel #-1,d2				***** a = a - (long long) 1;
	clrl d3					*****
	movel d3,sp@-
	movel d2,sp@-
	movel _a+4,sp@-
	movel _a,sp@-
	jbsr ___adddi3
[ lines discarded ...]
	movel #___adddi3,d0
	movel #-1,sp@-				***** a = a + (long long) -1;
	movel #-1,sp@-				*****
	movel _a+4,sp@-
	movel _a,sp@-
	jbsr ___adddi3
[ lines discarded ...]
% 

I hope it helps. (... to establish long long's as a part of GNU CC).

-- Erik