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 ])

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 ])

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.

No comments:

Post a Comment