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