[gnu.gcc.bug] gcc-1.30 compiler bug

gnu@GATECH.EDU (11/12/88)

Hello,

    I have gcc-1.30 up and running on my machine (a CRDS 68020 SysV Unix like
box using the Sun-3 config/tm files) and in the 68020 mode it works fine.
However, I have another box that uses a 68000 so I recompiled gcc-1.30 with
the flags "-m68000 -msoft-float" so that it could run on this other box (same
as my 68020, just 68000). The problem is that the compiler keeps getting an
abort code 127 whenever I run it on either my or the other machine now that
it has been recompiled to run on a 68000. A little investigation has shown
me where the problem is which I present to you now.

    Since the 68000 does not have a multiple instruction to handle two source
operands that are longs, the compiler makes a call to the library function
"__mulsi3" to perform the multiplications. As with GCC-1.30, my system compiler
considers registers D0 and D1 as scratch and available to any routine that is
called (i.e. the caller should not rely on these registers being saved after
calling a function). However, GCC-1.30 does not realize this when making the
call to "__mulsi3" and assumes that register D1 remains valid after the call
when in fact it has been changed.

    The section of the compiler that causes the abort(127) is in routine
reg_class_record() in the file regclass.c. Around line 591 of regclass.c, the
following code is indirectly responsible for the abort:

     for (i = 0; ; i++)
       {
	 class1 = reg_class_subclasses[(int)class][i];
	 .
	 .
	 .
       }

The reference to the array "reg_class_subclasses" requires use of the
"__mulsi3" routine. At this point in the compiled code, the compiler thinks
that register D1 is available and has not been modified when in fact it has.

The compiled code (for a 68000) for this section of code is:
(cut from regclass.s)

	clrl d1
	pea 56:w
	movel d2,sp@-
	jbsr __mulsi3
	movel d0,a1
	addl #_reg_class_subclasses,a1
L239:
	movel d1,d0
	asll #2,d0
	movel a1@(d0:l),d0			#1
	moveq #14,d6
	cmpl d0,d6
	jeq L238
	asll #1,d0
	addw d3,a0@(d0:l)
	addql #1,d1
	jra L239
L238:

Here, register D1 is the index "i" that is used to address the array stored
in address reg A1. However, the call to __mulsi3 has destroyed D1 and thus
the results of the access to the array (#1) are unpredictable. On my system,
D1 is replaced with 0x380000 and the code at (#1) references a location outside
of my program space. (sigh!)

    The problem seems to be that the compiler does not realize that it is
making actual function calls when it calls the library and that the compiler
must be constrained by the same rules as the rest of us when making
function calls (i.e. that registers D0 and D1 may be trashed after a
function call). Any thoughts on fixing this?

    If you need more info, please feel free to contact me.

Allan G. Schrum
3060 Business Park Drive, Ste. E
Norcross, GA 30071

!gatech!rebel!didsgn!{gnu|allan}