1 | /*****************************************************************************/ |
2 | /* */ |
3 | /* coptsize.c */ |
4 | /* */ |
5 | /* Size optimizations */ |
6 | /* */ |
7 | /* */ |
8 | /* */ |
9 | /* (C) 2002-2012, 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 | #include <stdlib.h> |
37 | |
38 | /* common */ |
39 | #include "cpu.h" |
40 | |
41 | /* cc65 */ |
42 | #include "codeent.h" |
43 | #include "codeinfo.h" |
44 | #include "coptsize.h" |
45 | #include "reginfo.h" |
46 | |
47 | |
48 | |
49 | /*****************************************************************************/ |
50 | /* Data */ |
51 | /*****************************************************************************/ |
52 | |
53 | |
54 | |
55 | /* Flags for CallDesc */ |
56 | #define F_NONE 0x0000U /* No extra flags */ |
57 | #define F_SLOWER 0x0001U /* Function call is slower */ |
58 | |
59 | typedef struct CallDesc CallDesc; |
60 | struct CallDesc { |
61 | const char* LongFunc; /* Long function name */ |
62 | RegContents Regs; /* Register contents */ |
63 | unsigned Flags; /* Flags from above */ |
64 | const char* ShortFunc; /* Short function name */ |
65 | }; |
66 | |
67 | /* Note: The table is sorted. If there is more than one entry with the same |
68 | ** name, entries are sorted best match first, so when searching linear for |
69 | ** a match, the first one can be used because it is also the best one (or |
70 | ** at least none of the following ones are better). |
71 | ** Note^2: Ptr1 and Tmp1 aren't evaluated, because runtime routines don't |
72 | ** expect parameters here. |
73 | */ |
74 | static const CallDesc CallTable [] = { |
75 | /* Name A register X register Y register flags replacement */ |
76 | { |
77 | "addeqysp" , |
78 | { |
79 | /* A X Y SRegLo */ |
80 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, |
81 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
82 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
83 | }, |
84 | F_NONE, |
85 | "addeq0sp" |
86 | },{ |
87 | "laddeq" , |
88 | { |
89 | /* A X Y SRegLo */ |
90 | 1, 0, UNKNOWN_REGVAL, 0, |
91 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
92 | 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
93 | }, |
94 | F_NONE, |
95 | "laddeq1" |
96 | },{ |
97 | "laddeq" , |
98 | { |
99 | /* A X Y SRegLo */ |
100 | UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, 0, |
101 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
102 | 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
103 | }, |
104 | F_NONE, |
105 | "laddeqa" |
106 | },{ |
107 | "laddeqysp" , |
108 | { |
109 | /* A X Y SRegLo */ |
110 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, |
111 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
112 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
113 | }, |
114 | F_NONE, |
115 | "laddeq0sp" |
116 | },{ |
117 | "ldaxidx" , |
118 | { |
119 | /* A X Y SRegLo */ |
120 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, 1, UNKNOWN_REGVAL, |
121 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
122 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
123 | }, |
124 | F_NONE, |
125 | "ldaxi" |
126 | },{ |
127 | "ldaxysp" , |
128 | { |
129 | /* A X Y SRegLo */ |
130 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, 1, UNKNOWN_REGVAL, |
131 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
132 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
133 | }, |
134 | F_NONE, |
135 | "ldax0sp" |
136 | },{ |
137 | "ldeaxidx" , |
138 | { |
139 | /* A X Y SRegLo */ |
140 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, 3, UNKNOWN_REGVAL, |
141 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
142 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
143 | }, |
144 | F_NONE, |
145 | "ldeaxi" |
146 | },{ |
147 | "ldeaxysp" , |
148 | { |
149 | /* A X Y SRegLo */ |
150 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, 3, UNKNOWN_REGVAL, |
151 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
152 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
153 | }, |
154 | F_NONE, |
155 | "ldeax0sp" |
156 | },{ |
157 | "leaaxsp" , |
158 | { |
159 | /* A X Y SRegLo */ |
160 | UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, |
161 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
162 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
163 | }, |
164 | F_NONE, |
165 | "leaa0sp" |
166 | },{ |
167 | "lsubeq" , |
168 | { |
169 | /* A X Y SRegLo */ |
170 | 1, 0, UNKNOWN_REGVAL, 0, |
171 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
172 | 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
173 | }, |
174 | F_NONE, |
175 | "lsubeq1" |
176 | },{ |
177 | "lsubeq" , |
178 | { |
179 | /* A X Y SRegLo */ |
180 | UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, 0, |
181 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
182 | 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
183 | }, |
184 | F_NONE, |
185 | "lsubeqa" |
186 | },{ |
187 | "lsubeqysp" , |
188 | { |
189 | /* A X Y SRegLo */ |
190 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, |
191 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
192 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
193 | }, |
194 | F_NONE, |
195 | "lsubeq0sp" |
196 | },{ |
197 | "pusha" , |
198 | { |
199 | /* A X Y SRegLo */ |
200 | 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, |
201 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
202 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
203 | }, |
204 | F_SLOWER, |
205 | "pushc0" |
206 | },{ |
207 | "pusha" , |
208 | { |
209 | /* A X Y SRegLo */ |
210 | 1, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, |
211 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
212 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
213 | }, |
214 | F_SLOWER, |
215 | "pushc1" |
216 | },{ |
217 | "pusha" , |
218 | { |
219 | /* A X Y SRegLo */ |
220 | 2, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, |
221 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
222 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
223 | }, |
224 | F_SLOWER, |
225 | "pushc2" |
226 | },{ |
227 | "pushax" , |
228 | { |
229 | /* A X Y SRegLo */ |
230 | 0, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, |
231 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
232 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
233 | }, |
234 | F_NONE, |
235 | "push0" |
236 | },{ |
237 | "pushax" , |
238 | { |
239 | /* A X Y SRegLo */ |
240 | 1, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, |
241 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
242 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
243 | }, |
244 | F_SLOWER, |
245 | "push1" |
246 | },{ |
247 | "pushax" , |
248 | { |
249 | /* A X Y SRegLo */ |
250 | 2, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, |
251 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
252 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
253 | }, |
254 | F_SLOWER, |
255 | "push2" |
256 | },{ |
257 | "pushax" , |
258 | { |
259 | /* A X Y SRegLo */ |
260 | 3, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, |
261 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
262 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
263 | }, |
264 | F_SLOWER, |
265 | "push3" |
266 | },{ |
267 | "pushax" , |
268 | { |
269 | /* A X Y SRegLo */ |
270 | 4, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, |
271 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
272 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
273 | }, |
274 | F_SLOWER, |
275 | "push4" |
276 | },{ |
277 | "pushax" , |
278 | { |
279 | /* A X Y SRegLo */ |
280 | 5, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, |
281 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
282 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
283 | }, |
284 | F_SLOWER, |
285 | "push5" |
286 | },{ |
287 | "pushax" , |
288 | { |
289 | /* A X Y SRegLo */ |
290 | 6, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, |
291 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
292 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
293 | }, |
294 | F_SLOWER, |
295 | "push6" |
296 | },{ |
297 | "pushax" , |
298 | { |
299 | /* A X Y SRegLo */ |
300 | 7, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, |
301 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
302 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
303 | }, |
304 | F_SLOWER, |
305 | "push7" |
306 | },{ |
307 | "pushax" , |
308 | { |
309 | /* A X Y SRegLo */ |
310 | UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, |
311 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
312 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
313 | }, |
314 | F_NONE, |
315 | "pusha0" |
316 | },{ |
317 | "pushax" , |
318 | { |
319 | /* A X Y SRegLo */ |
320 | UNKNOWN_REGVAL, 0xFF, UNKNOWN_REGVAL, UNKNOWN_REGVAL, |
321 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
322 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
323 | }, |
324 | F_SLOWER, |
325 | "pushaFF" |
326 | },{ |
327 | "pushaysp" , |
328 | { |
329 | /* A X Y SRegLo */ |
330 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, |
331 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
332 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
333 | }, |
334 | F_NONE, |
335 | "pusha0sp" |
336 | },{ |
337 | "pusheax" , |
338 | { |
339 | /* A X Y SRegLo */ |
340 | 0, 0, UNKNOWN_REGVAL, 0, |
341 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
342 | 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
343 | }, |
344 | F_NONE, |
345 | "pushl0" |
346 | },{ |
347 | "pusheax" , |
348 | { |
349 | /* A X Y SRegLo */ |
350 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, |
351 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
352 | 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
353 | }, |
354 | F_NONE, |
355 | "push0ax" |
356 | },{ |
357 | "pushwidx" , |
358 | { |
359 | /* A X Y SRegLo */ |
360 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, 1, UNKNOWN_REGVAL, |
361 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
362 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
363 | }, |
364 | F_NONE, |
365 | "pushw" |
366 | },{ |
367 | "pushwysp" , |
368 | { |
369 | /* A X Y SRegLo */ |
370 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, 3, UNKNOWN_REGVAL, |
371 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
372 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
373 | }, |
374 | F_NONE, |
375 | "pushw0sp" |
376 | },{ |
377 | "staxysp" , |
378 | { |
379 | /* A X Y SRegLo */ |
380 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, |
381 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
382 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
383 | }, |
384 | F_NONE, |
385 | "stax0sp" |
386 | },{ |
387 | "steaxysp" , |
388 | { |
389 | /* A X Y SRegLo */ |
390 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, |
391 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
392 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
393 | }, |
394 | F_NONE, |
395 | "steax0sp" |
396 | },{ |
397 | "subeqysp" , |
398 | { |
399 | /* A X Y SRegLo */ |
400 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, |
401 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
402 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
403 | }, |
404 | F_NONE, |
405 | "subeq0sp" |
406 | },{ |
407 | "tosaddax" , |
408 | { |
409 | /* A X Y SRegLo */ |
410 | UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, |
411 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
412 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
413 | }, |
414 | F_NONE, |
415 | "tosadda0" |
416 | },{ |
417 | "tosaddeax" , |
418 | { |
419 | /* A X Y SRegLo */ |
420 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, |
421 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
422 | 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
423 | }, |
424 | F_NONE, |
425 | "tosadd0ax" |
426 | },{ |
427 | "tosandax" , |
428 | { |
429 | /* A X Y SRegLo */ |
430 | UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, |
431 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
432 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
433 | }, |
434 | F_NONE, |
435 | "tosanda0" |
436 | },{ |
437 | "tosandeax" , |
438 | { |
439 | /* A X Y SRegLo */ |
440 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, |
441 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
442 | 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
443 | }, |
444 | F_NONE, |
445 | "tosand0ax" |
446 | },{ |
447 | "tosdivax" , |
448 | { |
449 | /* A X Y SRegLo */ |
450 | UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, |
451 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
452 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
453 | }, |
454 | F_NONE, |
455 | "tosdiva0" |
456 | },{ |
457 | "tosdiveax" , |
458 | { |
459 | /* A X Y SRegLo */ |
460 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, |
461 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
462 | 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
463 | }, |
464 | F_NONE, |
465 | "tosdiv0ax" |
466 | },{ |
467 | "toseqax" , |
468 | { |
469 | /* A X Y SRegLo */ |
470 | 0, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, |
471 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
472 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
473 | }, |
474 | F_NONE, |
475 | "toseq00" |
476 | },{ |
477 | "toseqax" , |
478 | { |
479 | /* A X Y SRegLo */ |
480 | UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, |
481 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
482 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
483 | }, |
484 | F_NONE, |
485 | "toseqa0" |
486 | },{ |
487 | "tosgeax" , |
488 | { |
489 | /* A X Y SRegLo */ |
490 | 0, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, |
491 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
492 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
493 | }, |
494 | F_NONE, |
495 | "tosge00" |
496 | },{ |
497 | "tosgeax" , |
498 | { |
499 | /* A X Y SRegLo */ |
500 | UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, |
501 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
502 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
503 | }, |
504 | F_NONE, |
505 | "tosgea0" |
506 | },{ |
507 | "tosgtax" , |
508 | { |
509 | /* A X Y SRegLo */ |
510 | 0, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, |
511 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
512 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
513 | }, |
514 | F_NONE, |
515 | "tosgt00" |
516 | },{ |
517 | "tosgtax" , |
518 | { |
519 | /* A X Y SRegLo */ |
520 | UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, |
521 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
522 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
523 | }, |
524 | F_NONE, |
525 | "tosgta0" |
526 | },{ |
527 | "tosicmp" , |
528 | { |
529 | /* A X Y SRegLo */ |
530 | UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, |
531 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
532 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
533 | }, |
534 | F_NONE, |
535 | "tosicmp0" |
536 | },{ |
537 | "tosleax" , |
538 | { |
539 | /* A X Y SRegLo */ |
540 | 0, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, |
541 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
542 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
543 | }, |
544 | F_NONE, |
545 | "tosle00" |
546 | },{ |
547 | "tosleax" , |
548 | { |
549 | /* A X Y SRegLo */ |
550 | UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, |
551 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
552 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
553 | }, |
554 | F_NONE, |
555 | "toslea0" |
556 | },{ |
557 | "tosltax" , |
558 | { |
559 | /* A X Y SRegLo */ |
560 | 0, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, |
561 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
562 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
563 | }, |
564 | F_NONE, |
565 | "toslt00" |
566 | },{ |
567 | "tosltax" , |
568 | { |
569 | /* A X Y SRegLo */ |
570 | UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, |
571 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
572 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
573 | }, |
574 | F_NONE, |
575 | "toslta0" |
576 | },{ |
577 | "tosmodax" , |
578 | { |
579 | /* A X Y SRegLo */ |
580 | UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, |
581 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
582 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
583 | }, |
584 | F_NONE, |
585 | "tosmoda0" |
586 | },{ |
587 | "tosmodeax" , |
588 | { |
589 | /* A X Y SRegLo */ |
590 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, |
591 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
592 | 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
593 | }, |
594 | F_NONE, |
595 | "tosmod0ax" |
596 | },{ |
597 | "tosmulax" , |
598 | { |
599 | /* A X Y SRegLo */ |
600 | UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, |
601 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
602 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
603 | }, |
604 | F_NONE, |
605 | "tosmula0" |
606 | },{ |
607 | "tosmuleax" , |
608 | { |
609 | /* A X Y SRegLo */ |
610 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, |
611 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
612 | 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
613 | }, |
614 | F_NONE, |
615 | "tosmul0ax" |
616 | },{ |
617 | "tosneax" , |
618 | { |
619 | /* A X Y SRegLo */ |
620 | UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, |
621 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
622 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
623 | }, |
624 | F_NONE, |
625 | "tosnea0" |
626 | },{ |
627 | "tosorax" , |
628 | { |
629 | /* A X Y SRegLo */ |
630 | UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, |
631 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
632 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
633 | }, |
634 | F_NONE, |
635 | "tosora0" |
636 | },{ |
637 | "tosoreax" , |
638 | { |
639 | /* A X Y SRegLo */ |
640 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, |
641 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
642 | 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
643 | }, |
644 | F_NONE, |
645 | "tosor0ax" |
646 | },{ |
647 | "tosrsubax" , |
648 | { |
649 | /* A X Y SRegLo */ |
650 | UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, |
651 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
652 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
653 | }, |
654 | F_NONE, |
655 | "tosrsuba0" |
656 | },{ |
657 | "tosrsubeax" , |
658 | { |
659 | /* A X Y SRegLo */ |
660 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, |
661 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
662 | 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
663 | }, |
664 | F_NONE, |
665 | "tosrsub0ax" |
666 | },{ |
667 | "tossubax" , |
668 | { |
669 | /* A X Y SRegLo */ |
670 | UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, |
671 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
672 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
673 | }, |
674 | F_NONE, |
675 | "tossuba0" |
676 | },{ |
677 | "tossubeax" , |
678 | { |
679 | /* A X Y SRegLo */ |
680 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, |
681 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
682 | 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
683 | }, |
684 | F_NONE, |
685 | "tossub0ax" |
686 | },{ |
687 | "tosudivax" , |
688 | { |
689 | /* A X Y SRegLo */ |
690 | UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, |
691 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
692 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
693 | }, |
694 | F_NONE, |
695 | "tosudiva0" |
696 | },{ |
697 | "tosudiveax" , |
698 | { |
699 | /* A X Y SRegLo */ |
700 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, |
701 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
702 | 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
703 | }, |
704 | F_NONE, |
705 | "tosudiv0ax" |
706 | },{ |
707 | "tosugeax" , |
708 | { |
709 | /* A X Y SRegLo */ |
710 | UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, |
711 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
712 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
713 | }, |
714 | F_NONE, |
715 | "tosugea0" |
716 | },{ |
717 | "tosugtax" , |
718 | { |
719 | /* A X Y SRegLo */ |
720 | UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, |
721 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
722 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
723 | }, |
724 | F_NONE, |
725 | "tosugta0" |
726 | },{ |
727 | "tosuleax" , |
728 | { |
729 | /* A X Y SRegLo */ |
730 | UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, |
731 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
732 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
733 | }, |
734 | F_NONE, |
735 | "tosulea0" |
736 | },{ |
737 | "tosultax" , |
738 | { |
739 | /* A X Y SRegLo */ |
740 | UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, |
741 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
742 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
743 | }, |
744 | F_NONE, |
745 | "tosulta0" |
746 | },{ |
747 | "tosumodax" , |
748 | { |
749 | /* A X Y SRegLo */ |
750 | UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, |
751 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
752 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
753 | }, |
754 | F_NONE, |
755 | "tosumoda0" |
756 | },{ |
757 | "tosumodeax" , |
758 | { |
759 | /* A X Y SRegLo */ |
760 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, |
761 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
762 | 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
763 | }, |
764 | F_NONE, |
765 | "tosumod0ax" |
766 | },{ |
767 | "tosumulax" , |
768 | { |
769 | /* A X Y SRegLo */ |
770 | UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, |
771 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
772 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
773 | }, |
774 | F_NONE, |
775 | "tosumula0" |
776 | },{ |
777 | "tosumuleax" , |
778 | { |
779 | /* A X Y SRegLo */ |
780 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, |
781 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
782 | 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
783 | }, |
784 | F_NONE, |
785 | "tosumul0ax" |
786 | },{ |
787 | "tosxorax" , |
788 | { |
789 | /* A X Y SRegLo */ |
790 | UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, |
791 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
792 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
793 | }, |
794 | F_NONE, |
795 | "tosxora0" |
796 | },{ |
797 | "tosxoreax" , |
798 | { |
799 | /* A X Y SRegLo */ |
800 | UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, |
801 | /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ |
802 | 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL |
803 | }, |
804 | F_NONE, |
805 | "tosxor0ax" |
806 | }, |
807 | |
808 | }; |
809 | #define CALL_COUNT (sizeof(CallTable) / sizeof(CallTable[0])) |
810 | |
811 | |
812 | |
813 | /*****************************************************************************/ |
814 | /* Helpers */ |
815 | /*****************************************************************************/ |
816 | |
817 | |
818 | |
819 | static const CallDesc* FindCall (const char* Name) |
820 | /* Find the function with the given name. Return a pointer to the table entry |
821 | ** or NULL if the function was not found. |
822 | */ |
823 | { |
824 | /* Do a binary search */ |
825 | int First = 0; |
826 | int Last = CALL_COUNT - 1; |
827 | int Found = 0; |
828 | |
829 | while (First <= Last) { |
830 | |
831 | /* Set current to mid of range */ |
832 | int Current = (Last + First) / 2; |
833 | |
834 | /* Do a compare */ |
835 | int Result = strcmp (CallTable[Current].LongFunc, Name); |
836 | if (Result < 0) { |
837 | First = Current + 1; |
838 | } else { |
839 | Last = Current - 1; |
840 | if (Result == 0) { |
841 | /* Found. Repeat the procedure until the first of all entries |
842 | ** with the same name is found. |
843 | */ |
844 | Found = 1; |
845 | } |
846 | } |
847 | } |
848 | |
849 | /* Return the first entry if found, or NULL otherwise */ |
850 | return Found? &CallTable[First] : 0; |
851 | } |
852 | |
853 | |
854 | |
855 | static int RegMatch (short Expected, short Actual) |
856 | /* Check for a register match. If Expected has a value, it must be identical |
857 | ** to Actual. |
858 | */ |
859 | { |
860 | return RegValIsUnknown (Expected) || (Expected == Actual); |
861 | } |
862 | |
863 | |
864 | |
865 | /*****************************************************************************/ |
866 | /* Code */ |
867 | /*****************************************************************************/ |
868 | |
869 | |
870 | |
871 | unsigned OptSize1 (CodeSeg* S) |
872 | /* Do size optimization by calling special subroutines that preload registers. |
873 | ** This routine does not work standalone, it needs a following register load |
874 | ** removal pass. |
875 | */ |
876 | { |
877 | CodeEntry* E; |
878 | unsigned Changes = 0; |
879 | unsigned I; |
880 | |
881 | /* Are we optimizing for size */ |
882 | int OptForSize = (S->CodeSizeFactor < 100); |
883 | |
884 | /* Walk over the entries */ |
885 | I = 0; |
886 | while (I < CS_GetEntryCount (S)) { |
887 | |
888 | const CallDesc* D; |
889 | |
890 | /* Get next entry */ |
891 | E = CS_GetEntry (S, I); |
892 | |
893 | /* Check if it's a subroutine call */ |
894 | if (E->OPC == OP65_JSR && (D = FindCall (E->Arg)) != 0) { |
895 | |
896 | /* Get input register info for this insn */ |
897 | const RegContents* In = &E->RI->In; |
898 | |
899 | /* FindCall finds the first entry that matches our function name. |
900 | ** The names are listed in "best match" order, so search for the |
901 | ** first one, that fulfills our conditions. |
902 | */ |
903 | while (1) { |
904 | |
905 | /* Check the registers and allow slower code only if |
906 | ** optimizing for size. |
907 | */ |
908 | if ((OptForSize || (D->Flags & F_SLOWER) == 0) && |
909 | RegMatch (D->Regs.RegA, In->RegA) && |
910 | RegMatch (D->Regs.RegX, In->RegX) && |
911 | RegMatch (D->Regs.RegY, In->RegY) && |
912 | RegMatch (D->Regs.SRegLo, In->SRegLo) && |
913 | RegMatch (D->Regs.SRegHi, In->SRegHi)) { |
914 | |
915 | /* Ok, match for all conditions */ |
916 | CodeEntry* X; |
917 | X = NewCodeEntry (E->OPC, E->AM, D->ShortFunc, 0, E->LI); |
918 | CS_InsertEntry (S, X, I+1); |
919 | CS_DelEntry (S, I); |
920 | |
921 | /* Remember that we had changes */ |
922 | ++Changes; |
923 | |
924 | /* Done */ |
925 | break; |
926 | } |
927 | |
928 | /* Next table entry, bail out if next entry not valid */ |
929 | if (++D >= CallTable + CALL_COUNT || |
930 | strcmp (D->LongFunc, E->Arg) != 0) { |
931 | /* End of table or entries reached */ |
932 | break; |
933 | } |
934 | } |
935 | } |
936 | |
937 | /* Next entry */ |
938 | ++I; |
939 | |
940 | } |
941 | |
942 | /* Return the number of changes made */ |
943 | return Changes; |
944 | } |
945 | |
946 | |
947 | |
948 | unsigned OptSize2 (CodeSeg* S) |
949 | /* Do size optimization by using shorter code sequences, even if this |
950 | ** introduces relations between instructions. This step must be one of the |
951 | ** last steps, because it makes further work much more difficult. |
952 | */ |
953 | { |
954 | unsigned Changes = 0; |
955 | unsigned I; |
956 | |
957 | /* Walk over the entries */ |
958 | I = 0; |
959 | while (I < CS_GetEntryCount (S)) { |
960 | |
961 | /* Get next entry */ |
962 | CodeEntry* E = CS_GetEntry (S, I); |
963 | |
964 | /* Get the input registers */ |
965 | const RegContents* In = &E->RI->In; |
966 | |
967 | /* Assume we have no replacement */ |
968 | CodeEntry* X = 0; |
969 | |
970 | /* Check the instruction */ |
971 | switch (E->OPC) { |
972 | |
973 | case OP65_LDA: |
974 | if (CE_IsConstImm (E)) { |
975 | short Val = (short) E->Num; |
976 | if (Val == In->RegX) { |
977 | X = NewCodeEntry (OP65_TXA, AM65_IMP, 0, 0, E->LI); |
978 | } else if (Val == In->RegY) { |
979 | X = NewCodeEntry (OP65_TYA, AM65_IMP, 0, 0, E->LI); |
980 | } else if (RegValIsKnown (In->RegA) && (CPUIsets[CPU] & CPU_ISET_65SC02) != 0) { |
981 | if (Val == ((In->RegA - 1) & 0xFF)) { |
982 | X = NewCodeEntry (OP65_DEA, AM65_IMP, 0, 0, E->LI); |
983 | } else if (Val == ((In->RegA + 1) & 0xFF)) { |
984 | X = NewCodeEntry (OP65_INA, AM65_IMP, 0, 0, E->LI); |
985 | } |
986 | } |
987 | } |
988 | break; |
989 | |
990 | case OP65_LDX: |
991 | if (CE_IsConstImm (E)) { |
992 | short Val = (short) E->Num; |
993 | if (RegValIsKnown (In->RegX) && Val == ((In->RegX - 1) & 0xFF)) { |
994 | X = NewCodeEntry (OP65_DEX, AM65_IMP, 0, 0, E->LI); |
995 | } else if (RegValIsKnown (In->RegX) && Val == ((In->RegX + 1) & 0xFF)) { |
996 | X = NewCodeEntry (OP65_INX, AM65_IMP, 0, 0, E->LI); |
997 | } else if (Val == In->RegA) { |
998 | X = NewCodeEntry (OP65_TAX, AM65_IMP, 0, 0, E->LI); |
999 | } |
1000 | } |
1001 | break; |
1002 | |
1003 | case OP65_LDY: |
1004 | if (CE_IsConstImm (E)) { |
1005 | short Val = (short) E->Num; |
1006 | if (RegValIsKnown (In->RegY) && Val == ((In->RegY - 1) & 0xFF)) { |
1007 | X = NewCodeEntry (OP65_DEY, AM65_IMP, 0, 0, E->LI); |
1008 | } else if (RegValIsKnown (In->RegY) && Val == ((In->RegY + 1) & 0xFF)) { |
1009 | X = NewCodeEntry (OP65_INY, AM65_IMP, 0, 0, E->LI); |
1010 | } else if (Val == In->RegA) { |
1011 | X = NewCodeEntry (OP65_TAY, AM65_IMP, 0, 0, E->LI); |
1012 | } |
1013 | } |
1014 | break; |
1015 | |
1016 | default: |
1017 | /* Avoid gcc warnings */ |
1018 | break; |
1019 | |
1020 | } |
1021 | |
1022 | /* Insert the replacement if we have one */ |
1023 | if (X) { |
1024 | CS_InsertEntry (S, X, I+1); |
1025 | CS_DelEntry (S, I); |
1026 | ++Changes; |
1027 | } |
1028 | |
1029 | /* Next entry */ |
1030 | ++I; |
1031 | |
1032 | } |
1033 | |
1034 | /* Return the number of changes made */ |
1035 | return Changes; |
1036 | } |
1037 | |