Added support for multiplication. Fixed peep hole bugs (and more functionality to...
[fw/sdcc] / src / pic / peeph.def
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 replace restart {
109         _NOTBITSKIP_    %1
110         _BITSKIP_       %2
111         goto    %3
112         %4
113 %3:     %5
114 } by {
115         ;peep 1 - test/jump to test/skip
116         %1
117         _INVERTBITSKIP_ %2
118         %4
119 %3:     %5
120
121
122 replace restart {
123         _NOTBITSKIP_    %1
124         _BITSKIP_       %2
125         goto    %3
126 %4:     %5
127 %3:     %6
128 } by {
129         ;peep 1b - test/jump to test/skip
130         %1
131         _INVERTBITSKIP_ %2
132 %4:     %5
133 %3:     %6
134
135
136 //replace restart {
137 //        btfss %1
138 //        goto  %2
139 //      %3
140 //%2:   %4
141 //} by {
142 //      ;peep 1 - test/jump to test/skip
143 //      btfsc   %1
144 //      %3
145 //%2:   %4
146 //}
147 //
148 //replace restart {
149 //        btfsc %1
150 //        goto  %2
151 //      %3
152 //%2:   %4
153 //} by {
154 //      ;peep 1a - test/jump to test/skip
155 //      btfss   %1
156 //      %3
157 //%2:   %4
158 //}
159 //
160 //replace restart {
161 //        btfss %1
162 //        goto  %4
163 //%2:   %3
164 //%4:   %5
165 //} by {
166 //      ;peep 1b - test/jump to test/skip
167 //      btfsc   %1
168 //%2:   %3
169 //%4:   %5
170 //}
171 //
172 //replace restart {
173 //        btfsc %1
174 //        goto  %4
175 //%2:   %3
176 //%4:   %5
177 //} by {
178 //      ;peep 1c - test/jump to test/skip
179 //      btfss   %1
180 //%2:   %3
181 //%4:   %5
182 //}
183
184
185 //bogus test for pcode
186 //replace restart {
187 //      movf    %1,w    ;comment at end
188 //%4:   movf    %1,w
189 //      RETURN
190 //      clrf    INDF
191 //      movlw   0xa5
192 //      movf    fsr,w
193 //      incf    indf,f
194 //      %2
195 //} by {
196 //      ; peep test remove redundant move
197 //%4:   movf    %1,w    ;another comment
198 //      %2
199 //} if AYBABTU %3
200
201
202 // peep 2
203 replace restart {
204         movwf   %1
205         movf    %1,w
206 } by {
207         ; peep 2 - Removed redundant move
208         movwf   %1
209 } if NZ
210
211 // peep 3
212 replace restart {
213         decf    %1,f
214         movf    %1,w
215         btfss   status,z
216         goto    %2
217 } by {
218         ; peep 3 - decf/mov/skpz to decfsz
219         decfsz  %1,f
220          goto   %2
221 }
222
223
224 replace restart {
225         movf    %1,w
226         movf    %1,w
227 } by {
228         ; peep 4 - Removed redundant move
229         movf    %1,w
230 }
231
232
233 replace restart {
234         movlw   %1
235         movwf   %2
236         movlw   %1
237 } by {
238         ; peep 5 - Removed redundant move
239         movlw   %1
240         movwf   %2
241 }
242
243 replace restart {
244         movwf   %1
245         movwf   %1
246 } by {
247         ; peep 6 - Removed redundant move
248         movwf   %1
249 }