// PIC Port Peep rules // // // INTRODUCTION: // // The peep hole optimizer searchs the // the SDCC generated code for small snippets // that can be optimized. As a user, you have // control over this optimization process without // having to learn the SDCC source code. (However // you'll still need access to the source since // these rules are compiled into the source.) // // The way it works is you specify the target // snippet that you want replaced with a more // efficient snippet that you write. Wild card // variables allow the rules to be parameterized. // // In all of the SDCC ports, labels and operands // can be wild cards. However, in the PIC even the // instructions can be wild cards. // // EXAMPLE: // // Consider Peep Rule 1 as an example. This rule // replaces some code like: // // skpz ;i.e. btfss status,Z // goto lab1 // clrw //lab1: // // with: // // skpnz ;i.e. btfsc status,Z // clrw //lab1 // // However, the Rule has four wild cards. // The first allows the btfss instruction operator // be anything, not just the Z bit in status register. // The second wild card applies to a label. // The third wild card is for an instruction - any // single instruction can be substituted. // The fourth wild card is also an instruction. It's // just an instruction place holder associated with // a label (think of it as the PIC Port author's laziness // imposed upon the user). // // // CONDITIONS // // There are certain instances where a peep rule may not // be applicable. Consider this subtle example: // // movwf R0 // movf R0,W // // It would seem that the second move is unnecessary. But // be careful! The movf instruction affects the 'Z' bit. // So if this sequence is followed by a btfsc status,Z, you // will have to leave the second move in. // // To get around this proble, the peep rule can be followed // by a conditon: "if NZ". Which is to say, apply the rule // if Z bit is not needed in the code that follows. The optimizer // is smart enough to look more than one instruction past the // target block... // // Special commands // // // _NOTBITSKIP_ %1 - Creates a wild card instruction that // will match all instructions except for // bit skip instructions (btfsc or btfss) // _BITSKIP_ %1 - Creates a wild card instruction that only // will match a bit skip instruction (btfsc // or btfss) // _INVERTBITSKIP_ %1 - For the wild card instruction %1, invert // the state of the bit skip. If %1 is not // a bit skip instruction, then there's an // error in the peep rule. // // // // Peep 1 // Converts // // btfss reg1,bit // goto label // incf reg2,f //label // // Into: // // btfsc reg1,bit // incf reg2,f //label // // Notice that wild cards will allow any instruction // besides incf to be used in the above. // // Also, notice that this snippet is not valid if // it follows another skip replace restart { _NOTBITSKIP_ %1 _BITSKIP_ %2 goto %3 %4 %3: %5 } by { ; peep 1 - test/jump to test/skip %1 _INVERTBITSKIP_ %2 %4 %3: %5 } replace restart { _NOTBITSKIP_ %1 _BITSKIP_ %2 goto %3 %4: %5 %3: %6 } by { ; peep 1b - test/jump to test/skip %1 _INVERTBITSKIP_ %2 %4: %5 %3: %6 } //bogus test for pcode //replace restart { // movf %1,w ;comment at end //%4: movf %1,w // RETURN // clrf INDF0 // movlw 0xa5 // movf fsr0,w // incf indf0,f // %2 //} by { // ; peep test remove redundant move //%4: movf %1,w ;another comment // %2 //} if AYBABTU %3 // peep 2 replace restart { movwf %1 movf %1,w } by { ; peep 2 - Removed redundant move movwf %1 } if NZ // peep 3 //replace restart { / decf %1,f /// movf %1,w // btfss _STATUS,z // goto %2 //} by { // ; peep 3 - decf/mov/skpz to decfsz // decfsz %1,f // goto %2 //} replace restart { movf %1,w movf %1,w } by { ; peep 4 - Removed redundant move movf %1,w } replace restart { movlw %1 movwf %2 movlw %1 } by { ; peep 5 - Removed redundant move movlw %1 movwf %2 } replace restart { movwf %1 movwf %1 } by { ; peep 6 - Removed redundant move movwf %1 } replace restart { movlw 0 iorwf %1,w } by { ; peep 7 - Removed redundant move movf %1,w } replace restart { movf %1,w movwf %2 decf %2,f } by { ; peep 8 - Removed redundant move decf %1,w movwf %2 } replace restart { movwf %1 movf %2,w xorwf %1,w } by { ; peep 9a - Removed redundant move movwf %1 xorwf %2,w } replace restart { movwf %1 movf %2,w iorwf %1,w } by { ; peep 9b - Removed redundant move movwf %1 iorwf %2,w } replace restart { movf %1,w movwf %2 movf %2,w } by { ; peep 9c - Removed redundant move movf %1,w movwf %2 } replace restart { movwf %1 movf %1,w movwf %2 } by { ; peep 9d - Removed redundant move movwf %1 movwf %2 } if NZ // From: Frieder Ferlemann replace restart { iorlw 0 } by { ; peep 10a - Removed unnecessary iorlw } if NZ // From: Frieder Ferlemann replace restart { xorlw 0 } by { ; peep 10b - Removed unnecessary xorlw } if NZ // From: Frieder Ferlemann replace restart { movf %1,w movwf %1 } by { ; peep 11 - Removed redundant move movf %1,w } replace restart { movf %1,w movf %2,w } by { ; peep 12 - Removed redundant move movf %2,w } replace restart { movf %1,w xorlw %2 bz %3 bra %4 %3: %5 } by { ; peep 101 - test for equality movlw %2 cpfseq %1 bra %4 %3: %5 }