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.
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment