Hi all,

I noticed that the PDK port is lacking a basic optimisation for conditional testing of single bits in IO registers (e.g. "if(PA & (1 << 4))"), where it uses a sequence of "mov.io", "and", "ceqsn"/"cneqsn" instructions, when instead it could be using "t0sn.io"/"t1sn.io" instructions.

I am trying to implement a couple of peephole rules to do this, but they aren't being applied everywhere I would expect them to. It seems to be that the "notUsed('a')" condition I have is misbehaving and thinks the A reg is used when it isn't. If I omit the notUsed('a') but leave everything else the same, the rules apply everywhere I expect them to.

My rules are as follows:

replace restart {
    mov.io    a, %1
    and    a, #%3
    ceqsn    a, #0x00
    goto    %2
} by {
    t0sn.io    %1, #%4
    goto    %2
    ; peephole replaced IO reg single bit test-and-branch with 't0sn' (pdk13). } if isPort('pdk13'), notUsed('a'), operandsLiteral(%3), immdInRange(0 7 'singleSetBit' %3 8 %4)

replace restart {
    mov.io    a, %1
    and    a, #%3
    cneqsn    a, #0x00
    goto    %2
} by {
    t1sn.io    %1, #%4
    goto    %2
    ; peephole replaced IO reg single bit test-and-branch with 't1sn' (pdk14, pdk15). } if isPort('pdk14' 'pdk15'), notUsed('a'), operandsLiteral(%3), immdInRange(0 7 'singleSetBit' %3 8 %4)

One example of a situation where the rules aren't being applied is:

void interrupt_handler(void) __interrupt(0) {
    if(INTRQ & INTRQ_T16) {
        timeout_expired = true;
        INTEN &= ~INTEN_T16;
        INTRQ &= ~INTRQ_T16;
    }
}

The assembly for that is:

_interrupt_handler:
    push    af
    mov    a, p
    push    af
    mov.io    a, __intrq
    and    a, #0x04
    ceqsn    a, #0x00
    goto    00111$
00112$:
    goto    00103$
00111$:
    mov    a, #0x01
    mov    _timeout_expired+0, a
    set0.io    __inten, #2
    set0.io    __intrq, #2
00103$:
    pop    af
    mov    p, a
    pop    af
    reti

You can see that for the lines following those that would match the first rule, no matter which branch is taken, the first use of A reg is to have something assigned to it - either "mov a, #0x01" or "pop af". The notUsed('a') condition should be returning true here.

Is notUsed() on PDK buggy, or am I missing something?

This is with RC2 of 4.4.0 (r14579) on Windows x64.

Regards,
Basil Hussain


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

Reply via email to