1 | /*****************************************************************************/ |
2 | /* */ |
3 | /* coptptrload.h */ |
4 | /* */ |
5 | /* Optimize loads through pointers */ |
6 | /* */ |
7 | /* */ |
8 | /* */ |
9 | /* (C) 2001-2009 Ullrich von Bassewitz */ |
10 | /* Roemerstrasse 52 */ |
11 | /* D-70794 Filderstadt */ |
12 | /* EMail: uz@cc65.org */ |
13 | /* */ |
14 | /* */ |
15 | /* This software is provided 'as-is', without any expressed or implied */ |
16 | /* warranty. In no event will the authors be held liable for any damages */ |
17 | /* arising from the use of this software. */ |
18 | /* */ |
19 | /* Permission is granted to anyone to use this software for any purpose, */ |
20 | /* including commercial applications, and to alter it and redistribute it */ |
21 | /* freely, subject to the following restrictions: */ |
22 | /* */ |
23 | /* 1. The origin of this software must not be misrepresented; you must not */ |
24 | /* claim that you wrote the original software. If you use this software */ |
25 | /* in a product, an acknowledgment in the product documentation would be */ |
26 | /* appreciated but is not required. */ |
27 | /* 2. Altered source versions must be plainly marked as such, and must not */ |
28 | /* be misrepresented as being the original software. */ |
29 | /* 3. This notice may not be removed or altered from any source */ |
30 | /* distribution. */ |
31 | /* */ |
32 | /*****************************************************************************/ |
33 | |
34 | |
35 | |
36 | #ifndef COPTPTRLOAD_H |
37 | #define COPTPTRLOAD_H |
38 | |
39 | |
40 | |
41 | /* cc65 */ |
42 | #include "codeseg.h" |
43 | |
44 | |
45 | |
46 | /*****************************************************************************/ |
47 | /* Code */ |
48 | /*****************************************************************************/ |
49 | |
50 | |
51 | |
52 | unsigned OptPtrLoad1 (CodeSeg* S); |
53 | /* Search for the sequence: |
54 | ** |
55 | ** clc |
56 | ** adc xxx |
57 | ** tay |
58 | ** txa |
59 | ** adc yyy |
60 | ** tax |
61 | ** tya |
62 | ** ldy |
63 | ** jsr ldauidx |
64 | ** |
65 | ** and replace it by: |
66 | ** |
67 | ** clc |
68 | ** adc xxx |
69 | ** sta ptr1 |
70 | ** txa |
71 | ** adc yyy |
72 | ** sta ptr1+1 |
73 | ** ldy |
74 | ** ldx #$00 |
75 | ** lda (ptr1),y |
76 | */ |
77 | |
78 | unsigned OptPtrLoad2 (CodeSeg* S); |
79 | /* Search for the sequence: |
80 | ** |
81 | ** adc xxx |
82 | ** pha |
83 | ** txa |
84 | ** iny |
85 | ** adc yyy |
86 | ** tax |
87 | ** pla |
88 | ** ldy |
89 | ** jsr ldauidx |
90 | ** |
91 | ** and replace it by: |
92 | ** |
93 | ** adc xxx |
94 | ** sta ptr1 |
95 | ** txa |
96 | ** iny |
97 | ** adc yyy |
98 | ** sta ptr1+1 |
99 | ** ldy |
100 | ** ldx #$00 |
101 | ** lda (ptr1),y |
102 | */ |
103 | |
104 | unsigned OptPtrLoad3 (CodeSeg* S); |
105 | /* Search for the sequence: |
106 | ** |
107 | ** lda #<(label+0) |
108 | ** ldx #>(label+0) |
109 | ** clc |
110 | ** adc xxx |
111 | ** bcc L |
112 | ** inx |
113 | ** L: ldy #$00 |
114 | ** jsr ldauidx |
115 | ** |
116 | ** and replace it by: |
117 | ** |
118 | ** ldy xxx |
119 | ** ldx #$00 |
120 | ** lda label,y |
121 | */ |
122 | |
123 | unsigned OptPtrLoad4 (CodeSeg* S); |
124 | /* Search for the sequence: |
125 | ** |
126 | ** lda #<(label+0) |
127 | ** ldx #>(label+0) |
128 | ** ldy #$xx |
129 | ** clc |
130 | ** adc (sp),y |
131 | ** bcc L |
132 | ** inx |
133 | ** L: ldy #$00 |
134 | ** jsr ldauidx |
135 | ** |
136 | ** and replace it by: |
137 | ** |
138 | ** ldy #$xx |
139 | ** lda (sp),y |
140 | ** tay |
141 | ** ldx #$00 |
142 | ** lda label,y |
143 | */ |
144 | |
145 | unsigned OptPtrLoad5 (CodeSeg* S); |
146 | /* Search for the sequence: |
147 | ** |
148 | ** jsr pushax |
149 | ** ldx #$00 |
150 | ** lda yyy |
151 | ** jsr tosaddax |
152 | ** ldy #$00 |
153 | ** jsr ldauidx |
154 | ** |
155 | ** and replace it by: |
156 | ** |
157 | ** sta ptr1 |
158 | ** stx ptr1+1 |
159 | ** ldy yyy |
160 | ** lda (ptr1),y |
161 | */ |
162 | |
163 | unsigned OptPtrLoad6 (CodeSeg* S); |
164 | /* Search for the sequence: |
165 | ** |
166 | ** jsr pushax |
167 | ** ldy xxx |
168 | ** ldx #$00 |
169 | ** lda (sp),y |
170 | ** jsr tosaddax |
171 | ** ldy #$00 |
172 | ** jsr ldauidx |
173 | ** |
174 | ** and replace it by: |
175 | ** |
176 | ** sta ptr1 |
177 | ** stx ptr1+1 |
178 | ** ldy xxx |
179 | ** lda (sp),y |
180 | ** tay |
181 | ** lda (ptr1),y |
182 | */ |
183 | |
184 | unsigned OptPtrLoad7 (CodeSeg* S); |
185 | /* Search for the sequence: |
186 | ** |
187 | ** jsr aslax1/shlax1 |
188 | ** clc |
189 | ** adc xxx |
190 | ** tay |
191 | ** txa |
192 | ** adc yyy |
193 | ** tax |
194 | ** tya |
195 | ** ldy zzz |
196 | ** jsr ldaxidx |
197 | ** |
198 | ** and replace it by: |
199 | ** |
200 | ** stx tmp1 |
201 | ** asl a |
202 | ** rol tmp1 |
203 | ** clc |
204 | ** adc xxx |
205 | ** sta ptr1 |
206 | ** lda tmp1 |
207 | ** adc yyy |
208 | ** sta ptr1+1 |
209 | ** ldy zzz |
210 | ** lda (ptr1),y |
211 | ** tax |
212 | ** dey |
213 | ** lda (ptr1),y |
214 | */ |
215 | |
216 | unsigned OptPtrLoad11 (CodeSeg* S); |
217 | /* Search for the sequence: |
218 | ** |
219 | ** clc |
220 | ** adc xxx |
221 | ** bcc L |
222 | ** inx |
223 | ** L: ldy #$00 |
224 | ** jsr ldauidx |
225 | ** |
226 | ** and replace it by: |
227 | ** |
228 | ** ldy xxx |
229 | ** sta ptr1 |
230 | ** stx ptr1+1 |
231 | ** ldx #$00 |
232 | ** lda (ptr1),y |
233 | */ |
234 | |
235 | unsigned OptPtrLoad12 (CodeSeg* S); |
236 | /* Search for the sequence: |
237 | ** |
238 | ** lda regbank+n |
239 | ** ldx regbank+n+1 |
240 | ** sta regsave |
241 | ** stx regsave+1 |
242 | ** clc |
243 | ** adc #$01 |
244 | ** bcc L0005 |
245 | ** inx |
246 | ** L: sta regbank+n |
247 | ** stx regbank+n+1 |
248 | ** lda regsave |
249 | ** ldx regsave+1 |
250 | ** ldy #$00 |
251 | ** jsr ldauidx |
252 | ** |
253 | ** and replace it by: |
254 | ** |
255 | ** ldy #$00 |
256 | ** ldx #$00 |
257 | ** lda (regbank+n),y |
258 | ** inc regbank+n |
259 | ** bne L1 |
260 | ** inc regbank+n+1 |
261 | ** L1: tay <- only if flags are used |
262 | ** |
263 | ** This function must execute before OptPtrLoad7! |
264 | ** |
265 | */ |
266 | |
267 | unsigned OptPtrLoad13 (CodeSeg* S); |
268 | /* Search for the sequence: |
269 | ** |
270 | ** lda zp |
271 | ** ldx zp+1 |
272 | ** ldy xx |
273 | ** jsr ldauidx |
274 | ** |
275 | ** and replace it by: |
276 | ** |
277 | ** ldy xx |
278 | ** ldx #$00 |
279 | ** lda (zp),y |
280 | */ |
281 | |
282 | unsigned OptPtrLoad14 (CodeSeg* S); |
283 | /* Search for the sequence: |
284 | ** |
285 | ** lda zp |
286 | ** ldx zp+1 |
287 | ** (anything that doesn't change a/x) |
288 | ** ldy xx |
289 | ** jsr ldauidx |
290 | ** |
291 | ** and replace it by: |
292 | ** |
293 | ** lda zp |
294 | ** ldx zp+1 |
295 | ** (anything that doesn't change a/x) |
296 | ** ldy xx |
297 | ** ldx #$00 |
298 | ** lda (zp),y |
299 | ** |
300 | ** Must execute before OptPtrLoad10! |
301 | */ |
302 | |
303 | unsigned OptPtrLoad15 (CodeSeg* S); |
304 | /* Search for the sequence: |
305 | ** |
306 | ** lda zp |
307 | ** ldx zp+1 |
308 | ** ldy xx |
309 | ** jsr ldaxidx |
310 | ** |
311 | ** and replace it by: |
312 | ** |
313 | ** ldy xx |
314 | ** lda (zp),y |
315 | ** tax |
316 | ** dey |
317 | ** lda (zp),y |
318 | */ |
319 | |
320 | unsigned OptPtrLoad16 (CodeSeg* S); |
321 | /* Search for the sequence |
322 | ** |
323 | ** ldy ... |
324 | ** jsr ldauidx |
325 | ** |
326 | ** and replace it by: |
327 | ** |
328 | ** ldy ... |
329 | ** stx ptr1+1 |
330 | ** sta ptr1 |
331 | ** ldx #$00 |
332 | ** lda (ptr1),y |
333 | ** |
334 | ** This step must be executed *after* OptPtrLoad1! |
335 | */ |
336 | |
337 | unsigned OptPtrLoad17 (CodeSeg* S); |
338 | /* Search for the sequence |
339 | ** |
340 | ** ldy ... |
341 | ** jsr ldaxidx |
342 | ** |
343 | ** and replace it by: |
344 | ** |
345 | ** ldy ... |
346 | ** sta ptr1 |
347 | ** stx ptr1+1 |
348 | ** lda (ptr1),y |
349 | ** tax |
350 | ** dey |
351 | ** lda (ptr1),y |
352 | ** |
353 | ** This step must be executed *after* OptPtrLoad9! While code size increases |
354 | ** by more than 200%, inlining will greatly improve visibility for the |
355 | ** optimizer, so often part of the code gets improved later. So we will mark |
356 | ** the step with less than 200% so it gets executed when -Oi is in effect. |
357 | */ |
358 | |
359 | unsigned OptPtrLoad18 (CodeSeg* S); |
360 | /* Search for the sequence: |
361 | ** |
362 | ** ldx #$xx |
363 | ** lda #$yy |
364 | ** clc |
365 | ** adc xxx |
366 | ** bcc L |
367 | ** inx |
368 | ** L: ldy #$00 |
369 | ** jsr ldauidx |
370 | ** |
371 | ** and replace it by: |
372 | ** |
373 | ** ldy xxx |
374 | ** ldx #$00 |
375 | ** lda $xxyy,y |
376 | ** |
377 | ** This is similar to OptPtrLoad3 but works on a constant address |
378 | ** instead of a label. Also, the initial X and A loads are reversed. |
379 | */ |
380 | |
381 | |
382 | unsigned OptPtrLoad19 (CodeSeg* S); |
383 | /* Search for the sequence: |
384 | ** |
385 | ** ldx #0 |
386 | ** and #mask (any value < 0x80) |
387 | ** jsr aslax1/shlax1 |
388 | ** clc |
389 | ** adc #<(label+0) |
390 | ** tay |
391 | ** txa |
392 | ** adc #>(label+0) |
393 | ** tax |
394 | ** tya |
395 | ** ldy #$01 |
396 | ** jsr ldaxidx |
397 | ** |
398 | ** and replace it by: |
399 | ** |
400 | ** and #mask (remove if == 0x7F) |
401 | ** asl |
402 | ** tay |
403 | ** lda label,y |
404 | ** ldx label+1,y |
405 | */ |
406 | |
407 | |
408 | /* End of coptptrload.h */ |
409 | |
410 | #endif |
411 | |