Sunday, July 15, 2012

Binutils 2.19.1 patch 1.4

Changes this version:

Fixed bug prohibiting the use of single quotes in a string Strings my be in either TI-style 'stuff' or C-style "stuff" TI-style strings follow E/A text rules C-style strings may include standard escape codes "example\n"

Download:
binutils-2.19.1-tms9900-1.4-patch.tar.gz

GCC 4.4.0 patch 1.6

Changes this version:

Fixed comparison against +-1 and +-2, were broken in 1.5
Prevented incorrect use of fake PC register for real work
Improved AND operations to reduce setup instructions
Fixed long-to-char conversions
Fixed post-increment pointers which live on the stack
Added optimization for setting byte quantities to zero
Added optimization for (int)X = (unsigned char)((int)X)
Removed double-counting saved registers on the stack
Reduced overhead needed for multiply instructions
Fixed bug causing structres to be loaded into registers
Structures used as function arguments now passed by reference
Fixed more bugs causing bad int-to-char conversions


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

Saturday, July 14, 2012

I was looking for another instance where int-to-char conversion was done incorrectly. Once again, GCC was assuming that byte quantities stored in registers are stored in the least significant byte. After much poking around, I found the problem in find_reloads. It was in a portion of code which was a default handler of reload conditions.

I had earlier fixed code in this function which handled most cases of subreg substitution, but I believe since the source and destination registers were the same in this case, execution skipped down to the default handler.

In any case, I added a check on that path to prevent modification of the subreg expression when int-to-char and char-to-int converstons are called for. These cases are properly handled in the machine description, and the correct instructions are issued as expected.

Unfortunately, once find_reloads was fixed, there was still a problem. The instruction was being broken in a different way, and looked something like this:

(insn 72 71 74 3 lucien2_8.c:39 (set (reg:QI 7 r7 [orig:73 D.1232 ] [73])
        (reg:QI 7 r7 [+1 ])) 71 {movqi} (nil))

This effectively returns us to the situation we just fixed, that the byte quantity was assumed to be in the least significant byte of a register.

After tracing execution and checking the evolution of the instruction, I found where the subreg expression was converted to the "+1" form above. This was done in alter_subreg.

The code there was intended to handle special cases which escaped processing by simplify_subreg. Since I've disabled a lot of sode which would remove subreg expressions, these default handlers are getting more use.

At this point, I need to go through my earlier notes, but I think it's time for another release.