1// PIC Port Peep rules 2// 3// 4// INTRODUCTION: 5// 6// The peep hole optimizer searchs the 7// the SDCC generated code for small snippets 8// that can be optimized. As a user, you have 9// control over this optimization process without 10// having to learn the SDCC source code. (However 11// you'll still need access to the source since 12// these rules are compiled into the source.) 13// 14// The way it works is you specify the target 15// snippet that you want replaced with a more 16// efficient snippet that you write. Wild card 17// variables allow the rules to be parameterized. 18// 19// In all of the SDCC ports, labels and operands 20// can be wild cards. However, in the PIC even the 21// instructions can be wild cards. 22// 23// EXAMPLE: 24// 25// Consider Peep Rule 1 as an example. This rule 26// replaces some code like: 27// 28// skpz ;i.e. btfss status,Z 29// goto lab1 30// clrw 31//lab1: 32// 33// with: 34// 35// skpnz ;i.e. btfsc status,Z 36// clrw 37//lab1 38// 39// However, the Rule has four wild cards. 40// The first allows the btfss instruction operator 41// be anything, not just the Z bit in status register. 42// The second wild card applies to a label. 43// The third wild card is for an instruction - any 44// single instruction can be substituted. 45// The fourth wild card is also an instruction. It's 46// just an instruction place holder associated with 47// a label (think of it as the PIC Port author's laziness 48// imposed upon the user). 49// 50// 51// CONDITIONS 52// 53// There are certain instances where a peep rule may not 54// be applicable. Consider this subtle example: 55// 56// movwf R0 57// movf R0,W 58// 59// It would seem that the second move is unnecessary. But 60// be careful! The movf instruction affects the 'Z' bit. 61// So if this sequence is followed by a btfsc status,Z, you 62// will have to leave the second move in. 63// 64// To get around this proble, the peep rule can be followed 65// by a conditon: "if NZ". Which is to say, apply the rule 66// if Z bit is not needed in the code that follows. The optimizer 67// is smart enough to look more than one instruction past the 68// target block... 69// 70// Special commands 71// 72// 73// _NOTBITSKIP_ %1 - Creates a wild card instruction that 74// will match all instructions except for 75// bit skip instructions (btfsc or btfss) 76// _BITSKIP_ %1 - Creates a wild card instruction that only 77// will match a bit skip instruction (btfsc 78// or btfss) 79// _INVERTBITSKIP_ %1 - For the wild card instruction %1, invert 80// the state of the bit skip. If %1 is not 81// a bit skip instruction, then there's an 82// error in the peep rule. 83// 84// 85// 86 87 88// Peep 1 89// Converts 90// 91// btfss reg1,bit 92// goto label 93// incf reg2,f 94//label 95// 96// Into: 97// 98// btfsc reg1,bit 99// incf reg2,f 100//label 101// 102// Notice that wild cards will allow any instruction 103// besides incf to be used in the above. 104// 105// Also, notice that this snippet is not valid if 106// it follows another skip 107 108 109replace restart { 110 _NOTBITSKIP_ %1 111 _BITSKIP_ %2 112 goto %3 113 %4 114%3: %5 115} by { 116 ; peep 1 - test/jump to test/skip 117 %1 118 _INVERTBITSKIP_ %2 119 %4 120%3: %5 121} 122 123replace restart { 124 _NOTBITSKIP_ %1 125 _BITSKIP_ %2 126 goto %3 127%4: %5 128%3: %6 129} by { 130 ; peep 1b - test/jump to test/skip 131 %1 132 _INVERTBITSKIP_ %2 133%4: %5 134%3: %6 135} 136 137 138//bogus test for pcode 139//replace restart { 140// movf %1,w ;comment at end 141//%4: movf %1,w 142// RETURN 143// clrf INDF0 144// movlw 0xa5 145// movf fsr0,w 146// incf indf0,f 147// %2 148//} by { 149// ; peep test remove redundant move 150//%4: movf %1,w ;another comment 151// %2 152//} if AYBABTU %3 153 154 155// peep 2 156replace restart { 157 movwf %1 158 movf %1,w 159} by { 160 ; peep 2 - Removed redundant move 161 movwf %1 162} if NZ 163 164// peep 3 165//replace restart { 166/ decf %1,f 167/// movf %1,w 168// btfss _STATUS,z 169// goto %2 170//} by { 171// ; peep 3 - decf/mov/skpz to decfsz 172// decfsz %1,f 173// goto %2 174//} 175 176 177replace restart { 178 movf %1,w 179 movf %1,w 180} by { 181 ; peep 4 - Removed redundant move 182 movf %1,w 183} 184 185 186replace restart { 187 movlw %1 188 movwf %2 189 movlw %1 190} by { 191 ; peep 5 - Removed redundant move 192 movlw %1 193 movwf %2 194} 195 196replace restart { 197 movwf %1 198 movwf %1 199} by { 200 ; peep 6 - Removed redundant move 201 movwf %1 202} 203 204replace restart { 205 movlw 0 206 iorwf %1,w 207} by { 208 ; peep 7 - Removed redundant move 209 movf %1,w 210} 211 212replace restart { 213 movf %1,w 214 movwf %2 215 decf %2,f 216} by { 217 ; peep 8 - Removed redundant move 218 decf %1,w 219 movwf %2 220} 221 222replace restart { 223 movwf %1 224 movf %2,w 225 xorwf %1,w 226} by { 227 ; peep 9a - Removed redundant move 228 movwf %1 229 xorwf %2,w 230} 231 232replace restart { 233 movwf %1 234 movf %2,w 235 iorwf %1,w 236} by { 237 ; peep 9b - Removed redundant move 238 movwf %1 239 iorwf %2,w 240} 241 242replace restart { 243 movf %1,w 244 movwf %2 245 movf %2,w 246} by { 247 ; peep 9c - Removed redundant move 248 movf %1,w 249 movwf %2 250} 251 252replace restart { 253 movwf %1 254 movf %1,w 255 movwf %2 256} by { 257 ; peep 9d - Removed redundant move 258 movwf %1 259 movwf %2 260} if NZ 261 262// From: Frieder Ferlemann 263 264replace restart { 265 iorlw 0 266} by { 267 ; peep 10a - Removed unnecessary iorlw 268} if NZ 269 270// From: Frieder Ferlemann 271 272replace restart { 273 xorlw 0 274} by { 275 ; peep 10b - Removed unnecessary xorlw 276} if NZ 277 278// From: Frieder Ferlemann 279 280replace restart { 281 movf %1,w 282 movwf %1 283} by { 284 ; peep 11 - Removed redundant move 285 movf %1,w 286} 287 288replace restart { 289 movf %1,w 290 movf %2,w 291} by { 292 ; peep 12 - Removed redundant move 293 movf %2,w 294} 295 296replace restart { 297 movf %1,w 298 xorlw %2 299 bz %3 300 bra %4 301%3: %5 302} by { 303 ; peep 101 - test for equality 304 movlw %2 305 cpfseq %1 306 bra %4 307%3: %5 308} 309