No more procrastinating, this won't get any easier.
During the UNSPEC_SUBREG experiment I found the places in reload where these problem expressions are identified. If a word-byte conversion is detected, a swpb instruction is performed on the offending register. The embedded subreg will be converted to a word-sized register by the existing code, and we should be OK.
Here is an example instruction before modification:
(insn 9 8 10 2 tursi5.c:6 (set (reg:QI 21 [ D.1197 ])
(plus:QI (subreg:QI (reg:HI 25) 1)
(const_int 48 [0x30]))) 59 {addqi3} (expr_list:REG_DEAD (reg:HI 25)
(nil)))
And after modification:
(insn 22 8 9 2 tursi5.c:6 (set (reg:QI 21 [ D.1197 ])
(subreg:QI (reg:HI 25) 1)) {movqi3}
(insn 9 8 10 2 tursi5.c:6 (set (reg:QI 21 [ D.1197 ])
(plus:HI (reg:HI 25)
(const_int 48 [0x30]))) 59 {addqi3} (expr_list:REG_DEAD (reg:HI 25)
(nil)))
Unfortunately, I need to tweak this a bit more:
div r3, r1
mov r2, r1
swpb r1 # <-- br="" finally="" here="" instruction="" is="" this=""> swpb r1 # \_ These are extras added due to multiple passes, ick
swpb r1 # /
ai r1, >3000
movb r1, @>8C00
I also need to make sure that I add code that peoperly handles all cases with embedded subregs.
So we have a few conditions to handle:
Subreg as operation destination:
(operation) (subreg R1) (reg) ->
(operation) (R1) (reg)
swpb R1 # Move value into byte position
Subreg as operation source:
(operation) (reg) (subreg) ->
swpb R1 # Prepare R1 for next operation
(operation) (R1) (reg)
swpb R1 # If needed, restore R1 for later use
The first one will probably never happen, due to how the instructions are processed, but the second one is definitely causing problems. It seems to only appear when a word-to-byte conversion is needed, and the value is stored in a register and the register will not be needed after that instruction. Even though that sounds like a fairly rare circumstance, it seems to happen more often than I would like.
-->
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment