Thursday, June 25, 2015

I was checking AtariAge today and one of the comments there had a really good idea. There should be some way to identify the patch revision in the compiler binary. I'll need to look into how to do that, but it's a really good idea.

Another idea: modify the gcc_installer script to find and use the most recent patches. It would be nice to not have to repackage the installer for every future patch. Also, there's no easy way to tell without unzipping it what patch versions are included in the distribution archive.

Also, there have been a lot of requests for a Windows installer. Can we get away with just installing cygwin and building from there? Can I get the installer to automatically adapt to the build environment? That would be really nice as well.

Monday, June 15, 2015

GCC 4.4.0 patch 1.11

Changes this version:

Fixed compilation error due to missing include in tms9900.h.
Fixed problem declaring global variables, they were not always exported
Some instruction sizes were defined incorrectly, causing assembly errors.
Fixed conditional jump displacement limits, they were too small.
Added compilation pass to add needed SWPB instructions.

Download: gcc-4.4.0-tms9900-1.11-patch.tar.gz

Saturday, June 13, 2015

More progress. I've added some debug output for this new pass. The idea is to follow the pattern of the other passes. This will provide some transparency in the compilation process as well as some breadcrumbs to folow in case things all go horribly wrong.

Here's an example instruction from a test program I used to verify the code which originally handled these subreg problems:

(insn 11 10 12 2 tursi5.c:6 (set (reg:QI 21 [ D.1197 ])
        (plus:QI (subreg:QI (reg:HI 25 [ Round+-1 ]) 1)
            (const_int 48 [0x30]))) 59 {addqi3} (expr_list:REG_DEAD (reg:HI 25 [ Round+-1 ])
        (nil)))

This is equivalent to the C expression "C=A+(char)B;"

In this instruction, we're trying to get the sum of a one-byte value and the least significant byte of a different two-byte value. On any other processor this wouldn't be a problem, and we could just ignore the subreg part since the addition instruction would just ignore the othr byte. Sadly for the TMS9900, we need to preserve the subreg because if the two-byte value is stored in a register, we need to move the least significant byte into the most-significant position before invoking the AB (Add Bytes) instruction.

So this pass now extracts that subreg expression into a seprate instruction before the add to handle the relocation if needed. Making a sequence like "D=(char)B; C=A+D". Here is the debug output describing this action.

From tursi5.c.171r.tms9900_subreg:

Modifying insn 11, extracting subreg to new instruction
scanning new insn with uid = 21.
New sequence:
(set:QI (reg:QI 29)
    (subreg:QI (reg:HI 25 [ Round+-1 ]) 1))
(insn 11 21 12 2 tursi5.c:6 (set (reg:QI 21 [ D.1197 ])
        (plus:QI (reg:QI 29)
            (const_int 48 [0x30]))) 59 {addqi3} (expr_list:REG_DEAD (reg:HI 25 [ Round+-1 ])
        (nil)))

Now, the RTL expressions can map more directly into opcodes, and if needed a SPWB instruction will be inserted to handle the type conversion before the addition.

OK, enough chatting, get to patching.

Friday, June 5, 2015

I've been spending some time thinking about the SWPB problem, and I think the only thing left to try is to add a new compilation pass before register assignment to fix these problem instructions. I've tried to avoid this, since it is very intrusive. Unfortunately, I can't think of a better method, and to be honest everything else I've tried has failed. OK, let's do it.

So I've got the framework of a new compilation pass in place, and it seems to be called where I wanted it in the compile process. This was placed between the pass checking for assembly constraints and the pass handling register assignment, which should be the right place. Unfortunately, this has increased the debug ID numbers of some nearby passes. This is kind of annoying, but not really a problem. For example, *172.ira is now *.173.ira.

OK, I got the new compilation pass done. So far it seems to work. Libgcc can be built without errors, and a test program known to require an additional SWPB instruction works as well. At this point I think I just need to do some cleanup and a little more testing. After that I can do a release. Finally.