Monday, July 20, 2015

I finally found a good place to put patch version information. Check it out:

eric@lenovo:~/dev/tios/src/gcc_installer/temp/out/bin$ ./tms9900-gcc --version
tms9900-gcc (GCC) 4.4.0 20090421 (TMS9900 patch 1.12)
Copyright (C) 2009 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

I also took a detour to see if I can get GCC 5.2 to work with my changes. So far, the merge is working out better than I thought, but there are still lots of errors. For some reason, the build of gcov fails. This is a profiling tool, and is required as part of the GCC build. This is all unmodified code, so I don't know why it's broken.

The problem seems to be related to the fact that we don't have libc headers for the TMS9900. I'm not sure why this is important since lots of other targets must be configured like this too. Unless I can figure out some way to make progress here, it may be time to give up for a while and get back to making a release.

Saturday, July 18, 2015

I was reading the changelog for more recent versions of GCC, and there's some nice stuff in there. This made me realize how old the gcc version 4.4.0 tree is. On the other hand, I've made a lot of changes to the internals of the compiler that would have to be ported to a newer version.

One thing I noticed is that I might be able to get proper handling of byte quantities by making custom operand types. The Arm back end does this to force values into the desired registers. But as I write this, I remember that the problem is that the compiler reasonably assumes that any place that can hold an int can be used for byte operations too. I  might have to stick with 4.4.0 for a while longer.

After fixing the overly broad parameter constrants for division I thought I should go through the other instructions as well. Unfortunately I found that same problem all over the place. Fixed now.

Sunday, July 12, 2015

I finally found the problem. One of the four descriptions for the division instruction in tms9900.md was wrong. All of the other descriptions forced the numerator to be in a register, this one allowed anything. So this let the constant 3200 be used directly, without the need to be stored in register. When that form was expanded, gen_highpart was called, resulting in the crash.

The error only showed up in this code because it contains lots of calculations, increasing the pressure on the compiler to make more efficient use of the registers. While doing that calculation it saw that the division form did not require a register and acted accordingly. The normal behavior is to put all values in registers before use. For less demanding code, that register usage would be left in place, and no error would be seen.

Once that was fixed, wolfie3 compiles without any problems, and the resulting assembly is correct. Yay!

Before I do any other releases, I want to try to make a cygwin archive for the windows people. I've been neglecting that for a long time.

Saturday, July 11, 2015

I finally got the new laptop working, and I started looking at the compiler crash for wolfie3.c. The problem looks like a bad subreg expression was added very early in the compilation process. Unfortunately, there is no output from the "-da" debug flag describing what that expression might be. I have no choice but to trace the error back from the location indicated by the failed assertion to a point where I can see what went wrong.

wolfie3.c: In function ‘cast_rays’:
wolfie3.c:278: internal compiler error: in subreg_highpart_offset, at emit-rtl.c:1308

The C code at that line looks like this:

#define SCREEN_DISTANCE 3200
unsigned int distance;
   ...
int sliceheight = SCREEN_DISTANCE / distance;


I changed all variables to unsigned int, thinking the difference in signedness was the problem. Nope, no change in error.

After adding some extra debug output, I think I found the problem.

EMW>> gen_highpart : (const_int 3200 [0xc80])
EMW>> subreg_highpart_offset : in=0 out=2 diff=-2

Someone is trying to take a subreg of a constant, which has no mode size. As a result, subreg_highpart_offset gets confused and aborts the compilation. Seeing that constant value is encouraging, since that shows I'm on the right track. Since this is a condition which should never happen, it's likely I wrote the code causing this problem. That narrows the scope quite a bit.