Hi all,

While browsing some assembly of my compiled code today, I noticed something that it seems the peephole optimiser did not catch, or is not looking for:

ld a, 0x5427
ld _can_rx_isr_prev_page_65537_99+0, a

This from a single line of C code doing a simple assignment from a register to a local static variable: "prev_page = CAN_PSR" (address of CAN_PSR register is 0x5427).

Seems unnecessary when both source and destination are memory-addressable. If there is no following dependency on the value of A or the state of N/Z CC flags (which in my example case here I'm 99.9% sure there isn't), surely this can be optimised to a single MOV instruction? For example:

mov _can_rx_isr_prev_page_65537_99+0, 0x5427

Only one cycle and 5 bytes, versus two cycles and 6 bytes.

I had a look at the peeph.def file for STM8 and I couldn't see any existing rules which attempted to substitute a MOV, so I think this may be a good candidate for an additional peephole optimiser rule for STM8.

What form would such a rule need to take? If I had to make a semi-informed guess, I would do:

replace {
    ld a, %1
    ld %2, a
} by {
    mov %2, %1
} if notUsed('a')

Does the rule need anything else? Something to assert that the %1 and %2 source/destination addresses are 'longmem' (or 'shortmem')? Some way of determining if any following instructions rely on N/Z flags (e.g. JRNE)?

Regards,
Basil Hussain

P.S. I also notice that later on in my function, when it does the inverse assignment of "CAN_PSR = prev_page", SDCC *does* generate a MOV instruction: "mov 0x5427+0, _can_rx_isr_prev_page_65537_99+0". I can't fathom why in one case, and not the other...


_______________________________________________
Sdcc-user mailing list
Sdcc-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sdcc-user

Reply via email to