Sunday, November 30, 2014

There was another problem reported that under some circumstances, jump tables were not being initialized correctly. What was actually happening was a lot more annoying to track down.

The problem was that the ASM_OUTPUT_COMMON macro that I stole from some other archetecture subverted the code used to track the currect segment. The code used to emit text into the assembly file is in varasm.c, in that file is a function called switch_to_section. It is intended to be responsib;e for all section switches. Each time a variable or code block is emitted, switch_to_section checks to see if the intended section is already in use. If not, the directives needed to switch sections are emitted. If the intended section is already in use, nothing happens.

The ASM_OUTPUT_COMMON macro, which outputs a variable in the .bss section, gratuitously emits a "cseg" directive to change the current segment. Later, the switch_to_section code, no knowing a section change has been made, might not do anything. The result is that objects which should be located in the code or data segments are mistakenly being placed in the bss section.

Like so many GCC problems, once the painful task of tacking down the problem is done, fixes are pretty straightforward. Basically, the fix is to use switch_to_section to change sections, like I should have done in the beginning.

Monday, November 10, 2014

OK, I've been trying to get the floating point library done before fixing the latest round of compiler bugs. Unfortunately, I'm stuck.

I got normalized multiplication working, but to be able to use denormal values in multiplication I will need to overhaul the design and basically start over. Ugh.

I was looking at the softfloat library at and it looks like it should work for the TMS9900 if the proper configuration is used. If that's the case, and the resulting code is not too large, my little effort might just be pointless.

Alright, enough fooling around. Lucien over at AtariAge was good enough to send a bunch of bugs he found, so let's get cracking.

First up, negating a byte quantity is done by calling "neg".

This is a problem in a couple of ways. First, if this were invoked on a value stored in memory, one of the neighboring bytes would be corrupted. Even if the value were stored in a register, if the low byte of the negated word is not zero, the resulting byte value will not be correct.

To fix this, I've forced all byte negation to be done in a register. The low byte is cleared, ensuring that after neg is called, the value will be correct.

I thought I fixed that earlier, but apparently not. At least it's done now.

The other problem was incorrectly using R0 as a base register for addressing memory. This is another easy one. There is a BASE_REG_CLASS macro used to determine if a register may be used as an address base, I changed the value to exclude R0 and all is well. While I was in that area, I noticed some junk code left over from the period when I was using fake registers. All that junk was been removed, and the code is more pretty. Yay.