/[projet1]/public/pc/tools/osdk/main/opt65/sources/opt65.c
Defence Force logotype

Contents of /public/pc/tools/osdk/main/opt65/sources/opt65.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1312 - (show annotations)
Sat Oct 24 09:07:43 2015 UTC (4 years, 3 months ago) by dbug
File MIME type: text/plain
File size: 53688 byte(s)
coFixed Coverity issues:
- 22033 Not checking for EOF on a fgetc call
- 22113 Non checked strcpy


1 /* Peephole-Optimzier V0.12
2
3 Written by Daniel Dallmann (aka Poldi)
4 This piece of software is freeware ! So DO NOT sell it !!
5 You may copy and redistribute this file for free, but only with this header
6 unchanged in it. (Or you risc eternity in hell)
7
8 If you've noticed a bug or created an additional feature, let me know.
9 My (internet) email-address is Daniel.Dallmann@studbox.uni-stuttgart.de
10 */
11
12 #include <stdlib.h>
13 #include <stdio.h>
14 #include <string.h>
15
16 #undef debug_parse
17 #undef debug_opti1
18 #undef debug_opti2
19 #undef debug
20
21 //#define debug
22
23 #ifdef debug
24 # define dbmsg(par) printf(par)
25 #else
26 # define dbmsg(par)
27 # define op2msg(par)
28 #endif
29
30
31 #define line_len 100
32
33 /* define tokens */
34
35 #define reg_a 0x0001
36 #define reg_x 0x0002
37 #define reg_y 0x0004
38 #define reg_s 0x0008
39 #define flag_d 0x0010
40 #define flag_n 0x0020
41 #define flag_v 0x0040
42 #define flag_z 0x0080
43 #define flag_c 0x0100
44 #define flag_i 0x0200
45 #define mem 0x0400
46 #define imem 0x0800
47
48 #define isjmp 0x0001 /* set, if command may cause a jump */
49 #define fixed 0x0002 /* set, if command should NOT be removed NOR moved */
50 #define dupl 0x0004 /* if command makes sense if repeated
51 eg. "sta xx, sta xx" doesn't make sense but
52 "inc xx, inc xx" makes sense */
53 #define isinit 0x0008 /* set, if commad initializes some flags or reg_y */
54
55 #define flag_nz (flag_n|flag_z)
56 #define flag_nzc (flag_n|flag_z|flag_c)
57 #define flag_arith (flag_nzc | flag_v)
58 #define reg_sr (flag_arith | flag_d|flag_i)
59
60 #define valid_map (reg_a | reg_x | reg_y | reg_s | reg_sr)
61
62 /* define tok-structure */
63
64 typedef struct {
65 char text[3];
66 int dep;
67 int mod;
68 int flags; } com;
69
70 /* table of assembler commands and their attributes */
71
72 #define tok_num 56
73 #define null_tok (tok_num+1)
74 #define no_tok (tok_num+2)
75
76 static com tok[tok_num]={
77
78 /* Name , depends on.. , modifies... , special flags */
79
80 { "cmp", reg_a|mem , flag_arith , 0 },
81 { "cpx", reg_x|mem , flag_arith , 0 },
82 { "cpy", reg_y|mem , flag_arith , 0 },
83
84 { "bit", reg_a|mem , flag_nzc|flag_v , fixed },
85
86 { "bcc", flag_c , 0 , isjmp },
87 { "bcs", flag_c , 0 , isjmp },
88 { "beq", flag_z , 0 , isjmp },
89 { "bne", flag_z , 0 , isjmp },
90 { "bmi", flag_n , 0 , isjmp },
91 { "bpl", flag_n , 0 , isjmp },
92 { "bvc", flag_v , 0 , isjmp },
93 { "bvs", flag_v , 0 , isjmp },
94
95 { "jmp", mem , 0 , isjmp },
96 { "jsr", reg_s|mem , reg_s|mem , isjmp },
97
98 { "asl", reg_a|mem , reg_a|flag_nzc|mem , dupl },
99 { "lsr", reg_a|mem , reg_a|flag_nzc|mem , dupl },
100 { "rol", reg_a|flag_c|mem , reg_a|flag_nzc|mem , dupl },
101 { "ror", reg_a|flag_c|mem , reg_a|flag_nzc|mem , dupl },
102
103 { "clc", 0 , flag_c , isinit },
104 { "cld", 0 , flag_d , isinit },
105 { "cli", 0 , flag_i , fixed },
106 { "clv", 0 , flag_v , isinit },
107 { "sec", 0 , flag_c , isinit },
108 { "sed", 0 , flag_d , isinit },
109 { "sei", 0 , flag_i , fixed },
110
111 { "nop", 0 , 0 , fixed },
112
113 { "rts", reg_s|mem , reg_s , isjmp },
114 { "rti", reg_s|mem , reg_s|reg_sr , isjmp },
115 { "brk", 0 , reg_s|reg_sr|mem , isjmp },
116
117 { "lda", mem , reg_a|flag_nz , 0 },
118 { "ldx", mem , reg_x|flag_nz , 0 },
119 { "ldy", mem , reg_y|flag_nz , isinit },
120
121 { "sta", reg_a , mem , 0 },
122 { "stx", reg_x , mem , 0 },
123 { "sty", reg_y , mem , 0 },
124
125 { "tax", reg_a , reg_x|flag_nz , 0 },
126 { "tay", reg_a , reg_y|flag_nz , isinit },
127 { "txa", reg_x , reg_a|flag_nz , 0 },
128 { "tya", reg_y , reg_a|flag_nz , 0 },
129 { "txs", reg_x , reg_s|flag_nz , 0 },
130 { "tsx", reg_s , reg_x|flag_nz , 0 },
131
132 { "pla", reg_s|mem , reg_a|reg_s|flag_nz , dupl },
133 { "plp", reg_s|mem , reg_sr|reg_s , dupl },
134 { "pha", reg_a|reg_s , reg_s|mem , dupl },
135 { "php", reg_sr|reg_s , reg_s|mem , dupl },
136
137 { "adc", reg_a|flag_c|flag_d|mem , reg_a|flag_arith , dupl },
138 { "sbc", reg_a|flag_c|flag_d|mem , reg_a|flag_arith , dupl },
139
140 { "inc", mem , mem|flag_nz , dupl },
141 { "dec", mem , mem|flag_nz , dupl },
142 { "inx", reg_x , reg_x|flag_nz , dupl },
143 { "dex", reg_x , reg_x|flag_nz , dupl },
144 { "iny", reg_y , reg_y|flag_nz , dupl|isinit },
145 { "dey", reg_y , reg_y|flag_nz , dupl|isinit },
146
147 { "and", reg_a|mem , reg_a|flag_nz , 0 },
148 { "ora", reg_a|mem , reg_a|flag_nz , 0 },
149 { "eor", reg_a|mem , reg_a|flag_nz , 0 }
150 };
151
152 #define as_cmp 0
153 #define as_cpx 1
154 #define as_cpy 2
155 #define as_bit 3
156 #define as_bcc 4
157 #define as_bcs 5
158 #define as_beq 6
159 #define as_bne 7
160 #define as_bmi 8
161 #define as_bpl 9
162 #define as_bvc 10
163 #define as_bvs 11
164 #define as_jmp 12
165 #define as_jsr 13
166 #define as_asl 14
167 #define as_lsr 15
168 #define as_rol 16
169 #define as_ror 17
170 #define as_clc 18
171 #define as_cld 19
172 #define as_cli 20
173 #define as_clv 21
174 #define as_sec 22
175 #define as_sed 23
176 #define as_sei 24
177 #define as_nop 25
178 #define as_rts 26
179 #define as_rti 27
180 #define as_brk 28
181 #define as_lda 29
182 #define as_ldx 30
183 #define as_ldy 31
184 #define as_sta 32
185 #define as_stx 33
186 #define as_sty 34
187 #define as_tax 35
188 #define as_tay 36
189 #define as_txa 37
190 #define as_tya 38
191 #define as_txs 39
192 #define as_tsx 40
193 #define as_pla 41
194 #define as_plp 42
195 #define as_pha 43
196 #define as_php 44
197 #define as_adc 45
198 #define as_sbc 46
199 #define as_inc 47
200 #define as_dec 48
201 #define as_inx 49
202 #define as_dex 50
203 #define as_iny 51
204 #define as_dey 52
205 #define as_and 53
206 #define as_ora 54
207 #define as_eor 55
208
209 typedef struct {
210 int tok; /* token of assembler-command */
211 int dep; /* command's result depends on... */
212 int mod; /* command modifies ... */
213 int depind; /* indirect depentencies */
214 int flags; /* special command-flags */
215 int feeds; /* command is used to calculate.. */
216 int passes; /* things that are unchanged and used later */
217 int par; /* command parameter */
218 int mpar; /* memory-address of dep or mod */
219 int mparhi; /* high-byte if indirect addressed*/
220 } line;
221
222 #define blkbuf_max 500 /* max blocksize of 500 lines should do the job */
223
224 static line blkbuf[blkbuf_max];
225 static int blkbuf_len;
226
227 #define par_max 200 /* max 200 different parameter should be enough */
228 #define par_length 10 /* just an average */
229 #define no_par (par_max+1)
230
231 static int par_num;
232 static int par_pos[par_max];
233 static int par_used;
234 static char parbuf[par_length*par_max];
235
236 static char mparbuf[par_length*par_max];
237 static int mpar_used;
238 static int mpar_num;
239 static int mpar_pos[par_max];
240
241 #define direct 0x0001
242 #define indirect 0x0002
243 #define xindexed 0x0004
244 #define yindexed 0x0008
245 #define absolute 0x2000 /* set, if there is a known immediate value */
246
247 static int mpar_flag[par_max];
248 #define undefd 0x0100
249
250 static int blk_mod;
251
252 static int com_match_lnum;
253 static line *com_match_lptr;
254 static int test_match;
255
256 static char tmpstr[100];
257
258 static int opt;
259 static int inp_line;
260 static int was_line;
261
262 char *getexpr(char *a, unsigned int *par);
263
264 /*********************************************************************/
265
266 void how_to()
267 {
268 printf("usage: opt65 file\n");
269 printf(" \"opt65\" is a peephole optimizer for 6502/10-assembler\n");
270 printf(" sources. The optimized code is printed to stdout.\n");
271 printf(" (This is version 0.12, Aug 23 1996, by 'Poldi')\n");
272 exit(1);
273 }
274
275 void ill_format()
276 {
277 printf("illegal file-format\n");
278 exit(1);
279 }
280
281 int readline(char *buf, FILE *infile)
282 {
283 static int x;
284 inp_line++;
285 x=0;
286 while (x<line_len-1)
287 {
288 int value=fgetc(infile);
289 buf[x]=(char)value;
290 if ( (buf[x]=='\n') || (buf[x]=='\0') || (value==EOF)) break;
291 x++;
292 }
293 if (x==0 && buf[x]==EOF) return EOF;
294 buf[x]='\0';
295 return 0;
296 }
297
298 void clear_buf()
299 {
300 dbmsg("clearing buffer...\n");
301
302 par_used=0;
303 par_num=0;
304
305 mpar_used=0;
306 mpar_num=0;
307 }
308
309 /*********************************************************************/
310
311 #ifdef debug
312
313 void mapout(int map)
314 {
315 if ( (map&reg_a )!=0 ) printf("A"); else printf("-");
316 if ( (map&reg_x )!=0 ) printf("X"); else printf("-");
317 if ( (map&reg_y )!=0 ) printf("Y"); else printf("-");
318 if ( (map&reg_s )!=0 ) printf("S"); else printf("-");
319 if ( (map&mem )!=0 ) printf("M"); else printf("-");
320 if ( (map&flag_n)!=0 ) printf("n"); else printf("-");
321 if ( (map&flag_z)!=0 ) printf("z"); else printf("-");
322 if ( (map&flag_c)!=0 ) printf("c"); else printf("-");
323 if ( (map&flag_v)!=0 ) printf("v"); else printf("-");
324 if ( (map&flag_d)!=0 ) printf("d"); else printf("-");
325 if ( (map&flag_i)!=0 ) printf("i"); else printf("-");
326 }
327
328 void lineout(line *p)
329 {
330 if ( p->tok==no_tok ) printf("???");
331 else if ( p->tok==null_tok ) printf("---");
332 else printf("%s",tok[p->tok].text);
333 printf(" dep:");
334 mapout(p->dep);
335 printf(" mod:");
336 mapout(p->mod);
337 printf(" feeds:");
338 mapout(p->feeds);
339 printf(" passes:");
340 mapout(p->passes);
341 printf(" fl:%2i",p->flags);
342 if (p->par!=no_par) {
343 printf(" \"%s\" [%i",&parbuf[par_pos[p->par]],p->par);
344 if (p->depind & mem) {
345 printf("/%i",p->mpar);
346 if (p->depind&imem ) printf(",%i",p->mparhi);
347 if (p->depind&reg_x) printf("Ix");
348 if (p->depind&reg_y) printf("Iy"); }
349 printf("]");
350 if (p->depind&absolute) printf(", val=%i",p->mpar); }
351 printf("\n");
352 }
353
354 void op2msg(char *a)
355 {
356 if (test_match) printf("### "); else printf("*** ");
357 printf("%s",a);
358 }
359
360 #endif
361
362 void bufout()
363 {
364 /* print block buffer */
365
366 int i;
367
368 i=0;
369 while (i<blkbuf_len) {
370 printf("\t %s",tok[blkbuf[i].tok].text);
371 if (blkbuf[i].par!=no_par) {
372 printf(" %s\n",&parbuf[par_pos[blkbuf[i].par]]); }
373 else printf("\n");
374 i++; }
375 }
376
377 /*********************************************************************/
378
379 int get_parid( char *par, int length)
380 {
381 int x,y;
382
383 y=0;
384 x=0;
385 while (x<par_num) {
386 y=0;
387 if (parbuf[par_pos[x]+length]!='\0') {
388 x++;
389 continue; }
390 while (y<length) {
391 if (parbuf[par_pos[x]+y]!=par[y]) {
392 y=0;
393 break; }
394 y++; }
395 if (y!=0) break;
396 x++; }
397
398 # ifdef debug_parse
399 if (y!=0) printf(", equal to par[%i]\n",x);
400 # endif
401
402 if (y==0) {
403
404 /* never seen this parameter before (in this block) so add it to list */
405
406 # ifdef debug_parse
407 printf(", added to database par[%i]\n",par_num);
408 # endif
409 y=0;
410 while (y<length) {
411 parbuf[par_used+y]=par[y];
412 y++; }
413 parbuf[par_used+y]='\0';
414
415 par_pos[par_num]=par_used;
416 par_used=par_used+length+1;
417 x=par_num;
418 par_num=par_num+1; }
419
420 return x;
421 }
422
423 int get_mparid( char *mpar, int length )
424 {
425 static int x,y;
426
427 y=0;
428 x=0;
429 while (x<mpar_num) {
430 y=0;
431 if (mparbuf[mpar_pos[x]+length]!='\0') {
432 x++;
433 continue; }
434 while (y<length) {
435 if (mparbuf[mpar_pos[x]+y]!=mpar[y]) {
436 y=0;
437 break; }
438 y++; }
439 if (y!=0) break;
440 x++; }
441
442 # ifdef debug_parse
443 if (y!=0) printf("existing mpar[%i]",x);
444 # endif
445
446 if (y==0) {
447
448 /* never seen this address before (in this block) so add it to list */
449
450 # ifdef debug_parse
451 printf("new mpar[%i]",mpar_num);
452 # endif
453
454 y=0;
455 while (y<length) {
456 mparbuf[mpar_used+y]=mpar[y];
457 y++; }
458 mparbuf[mpar_used+y]='\0';
459
460 mpar_pos[mpar_num]=mpar_used;
461 mpar_used=mpar_used+length+1;
462 x=mpar_num;
463 mpar_num++; }
464
465 # ifdef debug_parse
466 printf(":%s\n",&mparbuf[mpar_pos[x]]);
467 # endif
468
469 return x;
470 }
471
472 /*********************************************************************/
473
474 int is_sep(int c)
475 {
476 if (c>='0' && c<='9') return 0;
477 if (c>='a' && c<='z') return 0;
478 if (c>='A' && c<='Z') return 0;
479 if (c=='_') return 0;
480 if (c=='.') return 0;
481 return 1;
482 }
483
484 int nextchar(char *a, int i)
485 {
486 while ( a[i]==' ' || a[i]=='\t' ) i++;
487 return i;
488 }
489
490 char *getval(char *a, unsigned int *par)
491 {
492 static int i,cnt;
493 static unsigned int val;
494
495 cnt=0;
496 *par=0;
497 i=0;
498
499 if (a[i]=='#' || (a[i]>='0' && a[i]<='9')) {
500 /* get decimal value */
501 if (a[i]=='#') i=nextchar(a,i);
502 while (!is_sep(a[i])) {
503 if (a[i]>='0' && a[i]<='9') val=a[i]-'0';
504 else return NULL;
505 *par=*par*10+val;
506 cnt=cnt+1;
507 i=i+1; }
508 if (cnt==0) return NULL;
509 return &a[i]; }
510
511 if (a[i]=='$') {
512 /* get hex value */
513 i=nextchar(a,i+1);
514 while (!is_sep(a[i])) {
515 if (a[i]>='0' && a[i]<='9') val=a[i]-'0';
516 else if (a[i]>='a' && a[i]<='f') val=a[i]-'a'+10;
517 else return NULL;
518 *par=*par*16+val;
519 cnt=cnt+1;
520 i=i+1; }
521 if (cnt==0) return NULL;
522 return &a[i]; }
523
524 if (a[i]=='%') {
525 /* get binary value */
526 i=nextchar(a,i+1);
527 while (!is_sep(a[i])) {
528 if (a[i]=='0') val=0;
529 else if (a[i]=='1') val=1;
530 else return NULL;
531 *par=*par*2+val;
532 cnt=cnt+1;
533 i=i+1; }
534 if (cnt==0) return NULL;
535 return &a[i]; }
536
537 /* nothing of the obove, so it must be a label */
538 /* i can't resolve label-values, sorry ! */
539
540 return NULL;
541 }
542
543
544 char *getterm(char *a, unsigned int *par)
545 {
546
547 if (*a=='<') {
548 /* take lowbyte of term */
549 a=getterm(&a[1], par);
550 if (*par>0xffff) return NULL;
551 *par=*par&255;
552 return a; }
553
554 if (*a=='>') {
555 /* take highbyte of term */
556 a=getterm(&a[1], par);
557 if (*par>0xffff) return NULL;
558 *par=(*par>>8)&255;
559 return a; }
560
561 if (*a=='(') {
562 a=getexpr(&a[1], par);
563 if (a==NULL) return NULL;
564 a=&a[nextchar(a,0)];
565 if (*a!=')') return NULL;
566 return &a[1]; }
567 else
568 return getval(a, par);
569 }
570
571 char *getexpr(char *a, unsigned int *par)
572 {
573 unsigned int tmp;
574
575 a=getterm(a, par);
576 if (a==NULL) return NULL;
577
578 while (1) {
579
580 if (*a=='+') {
581 tmp=*par;
582 a=getterm(&a[1], par);
583 if (a==NULL) return NULL;
584 *par=*par+tmp;
585 continue; }
586
587 if (*a=='-') {
588 tmp=*par;
589 a=getterm(&a[1], par);
590 if (a==NULL) return NULL;
591 *par=tmp-*par;
592 continue; }
593
594 if (*a=='*') {
595 tmp=*par;
596 a=getterm(&a[1], par);
597 if (a==NULL) return NULL;
598 *par=tmp* *par;
599 continue; }
600
601 if (*a=='/') {
602 tmp=*par;
603 a=getterm(&a[1], par);
604 if (a==NULL) return NULL;
605 *par=tmp/(*par);
606 continue; }
607
608 break; }
609
610 return a;
611 }
612
613 /*********************************************************************/
614
615 int resolve_abs(char *a)
616 {
617 static unsigned int tmp;
618
619 # ifdef debug_parse
620 printf("try to resolve \"%s\", ",a);
621 # endif
622
623 if (getexpr(a, &tmp)==NULL) { dbmsg("sorry\n"); return undefd; }
624 if (tmp>0xff) { dbmsg("sorry >255\n"); return undefd; }
625 else {
626 # ifdef debug_parse
627 printf("value is %i\n",tmp);
628 # endif
629 return tmp; }
630 }
631
632 /* parse_line returns a value unequal to zero, if line includes
633 a label-definition */
634
635 int parse_line(char *a, line *p)
636 {
637 static int i,j,x;
638
639 p->tok=null_tok;
640 p->dep=0;
641 p->mod=0;
642 p->feeds=0;
643 p->passes=0;
644 p->depind=0;
645 p->flags=0;
646 p->mpar=0;
647 p->mparhi=0;
648 p->par=no_par;
649
650 # ifdef debug_parse
651 printf("line=\"%s\"\n",a);
652 # endif
653
654 /* remove leading white_spaces */
655
656 i=nextchar(a,0);
657 if (a[i]=='\0') return 0;
658 if (a[i]==';' ) return 0;
659
660 /* check for assembler-command */
661
662 j=0;
663 while (j<tok_num &&
664 !( a[i ]==tok[j].text[0]
665 && a[i+1]==tok[j].text[1]
666 && a[i+2]==tok[j].text[2] ) ) j++;
667 if (j==tok_num) {
668 while (a[i]!=' ' && a[i]!='\t' && a[i]!='\0') i++;
669 x=parse_line(&a[i], p);
670 if (x!=0) return 2;
671 return 1; }
672
673 /* check for addressing mode */
674
675 p->tok=j;
676 p->dep=tok[j].dep;
677 p->mod=tok[j].mod;
678 p->flags=tok[j].flags;
679 p->par=no_par;
680
681 i=nextchar(a,i+3);
682 if ( a[i]=='\0' || a[i]==';' ) return 0;
683
684 /* hey, there seem to be a parameter */
685 /* let's remove comments and white spaces */
686
687 j=i;
688 while (a[j]!='\0' && a[j]!=';') j++; /* search end of parameter */
689 while (j>i)
690 {
691 if (a[j-1]!=' ' && a[j-1]!='\t') break;
692 j=j-1;
693 }
694 j=j-i;
695
696 # ifdef debug_parse
697 a[i+j]='\0';
698 printf("par is \"%s\"",&a[i]);
699 # endif
700
701 /* now i points to start and j is length of parameter-string */
702
703 p->par=x=get_parid(&a[i],j);
704
705 if (j==1 && (a[i]=='a'||a[i]=='A') ) return 0; /* Akku addressed */
706 if (a[i]=='#')
707 { /* immediate */
708 if ( (p->mpar=resolve_abs(&parbuf[par_pos[x]+1]))!=undefd )
709 p->depind|=absolute; /* resolved */
710 return 0;
711 }
712
713 if ( a[i]=='(' )
714 {
715 i++;
716 while ( a[i]==' ' || a[i]=='\t' ) i++;
717 p->depind=p->depind|imem; /* indirect-flag */
718 }
719
720 p->depind=p->depind|mem;
721
722 j=i;
723 while ( a[j]!='\0' && a[j]!=';' && a[j]!=',' && a[j]!=')'
724 && a[j]!=' ' && a[j]!='\t' ) j++;
725 j=j-i;
726
727 /* now "i" exactly points to start of mem-address, j is length */
728
729 x=get_mparid( &a[i], j );
730 p->mpar=x;
731
732 if (p->depind & imem)
733 {
734 /* address points to 16bit-pointer */
735 strncpy(tmpstr,&a[i],sizeof(tmpstr));
736 tmpstr[sizeof(tmpstr)-1]=0;
737 tmpstr[j]='+';
738 tmpstr[j+1]='1';
739 p->mparhi=get_mparid( tmpstr, j+2 ); }
740
741 i=i+j;
742
743 /* scan for ",x" and ",y" idexes */
744
745 x=0;
746 while (1)
747 {
748 if (a[i]=='\0'||a[i]==';') break;
749 if (a[i]==' '||a[i]=='\t') { i++; continue; }
750 if (a[i]==',') { x=1; i++; continue; }
751 if (a[i]=='x' && x==1) { x=2; i++; continue; }
752 if (a[i]=='y' && x==1) { x=3; i++; continue; }
753 x=0; i++;
754 }
755
756 if (x==2)
757 {
758 p->dep=p->dep|reg_x;
759 p->depind=p->depind|reg_x;
760 }
761 if (x==3)
762 {
763 p->dep=p->dep|reg_y;
764 p->depind=p->depind|reg_y;
765 }
766 return 0;
767 }
768
769 /*********************************************************************/
770
771 void line_copy(line *to, line *from)
772 {
773 to->tok =from->tok;
774 to->dep =from->dep;
775 to->mod =from->mod;
776 to->flags =from->flags;
777 to->feeds =from->feeds;
778 to->passes =from->passes;
779 to->depind =from->depind;
780 to->par =from->par;
781 to->mpar =from->mpar;
782 to->mparhi =from->mparhi;
783 }
784
785 #define iline_copy(par1,par2) line_copy(&blkbuf[par1],&blkbuf[par2])
786
787 /*********************************************************************/
788
789 void make_feedlist()
790 {
791 static int hlp;
792 static int i;
793 static line *p;
794
795 dbmsg("making feedlist...\n");
796
797 hlp=blk_mod;
798 if (blkbuf_len<1) return;
799 i=0;
800 while (i<mpar_num) mpar_flag[i++]=1;
801
802 i=blkbuf_len-1;
803 while( i>=0 ) {
804 p=&blkbuf[i];
805 p->feeds=p->mod & hlp;
806 p->passes=hlp & ~p->mod;
807 hlp=((hlp & ( ~p->mod ))) | (p->dep & valid_map);
808
809 if (p->depind & mem) {
810
811 if (p->depind & imem) {
812
813 /* command depends/modifies memory through a 16bit pointer*/
814 /* don't now how to handle, so always set feed-flag */
815
816 if (p->mod & mem) p->feeds|=mem;
817
818 /* dep: ptr,ptr+1 */
819
820 mpar_flag[p->mpar]=1;
821 mpar_flag[p->mparhi]=1; }
822
823 else if (p->depind & (reg_x|reg_y) ) {
824
825 /* indexed addressmode (,x or ,y) */
826 /* don't know the exact address, so always set feed-flag */
827
828 if (p->mod & mem) p->feeds|=mem;
829
830 /* dep: ptr */
831
832 mpar_flag[p->mpar]=1; }
833
834 else
835
836 /* normal addressed memory (direct) */
837
838 if ( mpar_flag[p->mpar] ) {
839 if ((p->mod & mem)!=0) {
840 p->feeds|=mem;
841 mpar_flag[p->mpar]=0; }
842 else p->passes|=mem; }
843
844 if (p->dep & mem) {
845 mpar_flag[p->mpar]=1; } }
846
847 i--; }
848 }
849
850 /*********************************************************************/
851
852 int simple_erase()
853 {
854 /* erase all commands, that don't feed a register/flag nor change memory
855 nor are fixed */
856
857 int i,j;
858
859 i=0; j=0;
860 while (i<blkbuf_len) {
861 if (blkbuf[i].feeds==0 && (blkbuf[i].flags&fixed)==0) {
862 /* erase it ! */
863 # ifdef debug
864 printf("*** simple_erased: buf[%i]\n",i);
865 # endif
866 opt++;
867 i++;
868 continue; }
869 if (i!=j) line_copy(&blkbuf[j],&blkbuf[i]);
870 i++; j++; }
871
872 blkbuf_len=j;
873 return (i!=j);
874 }
875
876 /*********************************************************************/
877
878 void set_absval(line *p, int val)
879 {
880 static char par[5];
881
882 sprintf(par,"#%i",val);
883
884 p->par=get_parid(par, strlen(par));
885 p->depind=absolute;
886 }
887
888 int opti1()
889 {
890 /* do some clean up */
891
892 line *p;
893 int i,j,val,done;
894 int rega;
895 int regx;
896 int regy;
897 int *par;
898 int flag;
899
900 rega=regx=regy=undefd;
901 i=0; j=0; flag=0;
902 while (i<mpar_num) mpar_flag[i++]=undefd;
903
904 i=0;
905 while (i<blkbuf_len) {
906 p=&blkbuf[i];
907 done=0;
908
909 if (p->par!=no_par && (p->depind&mem)==0) { /* mem=0 so its # or a */
910 if (p->depind&absolute) val=p->mpar; else val=undefd;
911
912 switch (p->tok) {
913
914 case as_lda: {
915 if (rega==val && val!=undefd && (p->feeds&reg_sr)==0) {
916 # ifdef debug_opti1
917 printf("*** %i redundant lda#\n",i);
918 # endif
919 done=2; }
920 else done=1;
921 rega=val;
922 break; }
923
924 case as_ldx: {
925 if (regx==val && val!=undefd && (p->feeds&reg_sr)==0) {
926 # ifdef debug_opti1
927 printf("*** %i redundant ldx#\n",i);
928 # endif
929 done=2; }
930 else done=1;
931 regx=val;
932 break; }
933
934 case as_ldy: {
935 if (regy==val && val!=undefd && (p->feeds&reg_sr)==0) {
936 # ifdef debug_opti1
937 printf("*** %i redundant ldy#\n",i);
938 # endif
939 done=2; }
940 else done=1;
941 regy=val;
942 break; }
943
944 case as_and: {
945 if ( (val!=undefd && rega!=undefd) || val==0 || rega==0 ) {
946 rega&=val;
947 # ifdef debug_opti1
948 printf("### %i known and#-result #%i\n", i, rega);
949 # endif
950 /* replace "and #nn" with "lda #" */
951 set_absval(p,rega);
952 p->tok=as_lda;
953 p->dep=tok[as_lda].dep; p->flags=tok[as_lda].flags;
954 flag=done=1; }
955 else {
956 if ( (val==0xff) && (p->feeds&reg_sr)==0 ) {
957 # ifdef debug_opti1
958 printf("*** %i redundant and#\n",i);
959 # endif
960 done=2; }
961 else done=1;
962 rega=undefd; }
963 break; }
964
965 case as_ora: {
966 if ( (val!=undefd && rega!=undefd) || val==0xff || rega==0xff ) {
967 rega|=val;
968 # ifdef debug_opti1
969 printf("### %i known ora#-result #%i\n", i, rega);
970 # endif
971 /* replace "ora #nn" with "lda #" */
972 set_absval(p,rega);
973 p->tok=as_lda;
974 p->dep=tok[as_lda].dep; p->flags=tok[as_lda].flags;
975 flag=done=1; }
976 else {
977 if ( (val==0) && (p->feeds&reg_sr)==0 ) {
978 # ifdef debug_opti1
979 printf("*** %i redundant ora#\n",i);
980 # endif
981 done=2; }
982 else done=1;
983 rega=undefd; }
984 break; }
985
986 case as_eor: {
987 if ( val!=undefd && rega!=undefd ) {
988 rega^=val;
989 # ifdef debug_opti1
990 printf("### %i known eor#-result #%i\n", i, rega);
991 # endif
992 /* replace "eor #nn" with "lda #" */
993 set_absval(p,rega);
994 p->tok=as_lda;
995 p->dep=tok[as_lda].dep; p->flags=tok[as_lda].flags;
996 flag=done=1; }
997 else {
998 if ( (val==0) && (p->feeds&reg_sr)==0 ) {
999 # ifdef debug_opti1
1000 printf("*** %i redundant eor#\n",i);
1001 # endif
1002 done=2; }
1003 else done=1;
1004 rega=undefd; }
1005 break; }
1006 }
1007 }
1008
1009 if ( (p->depind & (mem|imem|reg_x|reg_y))==mem ) {
1010 par=&mpar_flag[p->mpar];
1011
1012 switch (p->tok) {
1013
1014 case as_sta: {
1015 if (*par==rega && rega!=undefd) {
1016 # ifdef debug_opti1
1017 printf("*** %i redundant sta\n",i);
1018 # endif
1019 done=2; }
1020 else done=1;
1021 *par=rega;
1022 break; }
1023
1024 case as_stx: {
1025 if (*par==regx && regx!=undefd) {
1026 # ifdef debug_opti1
1027 printf("*** %i redundant stx\n",i);
1028 # endif
1029 done=2; }
1030 else done=1;
1031 *par=regx;
1032 break; }
1033
1034 case as_sty: {
1035 if (*par==regy && regy!=undefd) {
1036 # ifdef debug_opti1
1037 printf("*** %i redundant sty\n",i);
1038 # endif
1039 done=2; }
1040 else done=1;
1041 *par=regy;
1042 break; }
1043
1044 case as_inc: { if (*par!=undefd) *par=0xff&(*par+1); done=1; break; }
1045
1046 case as_dec: { if (*par!=undefd) *par=0xff&(*par-1); done=1; break; }
1047
1048 case as_and: {
1049 if ( (*par!=undefd && rega!=undefd) || *par==0 || rega==0 ) {
1050 rega&=*par;
1051 # ifdef debug_opti1
1052 printf("*** %i known and-result #%i\n", i, rega);
1053 # endif
1054 /* replace "and adr" with "lda #" */
1055 set_absval(p,rega);
1056 p->tok=as_lda;
1057 p->dep=tok[as_lda].dep; p->flags=tok[as_lda].flags;
1058 opt++;
1059 flag=done=1; }
1060 else {
1061 if ( *par==0xff && (p->feeds&reg_sr)==0 ) {
1062 # ifdef debug_opti1
1063 printf("*** %i redundant and\n",i);
1064 # endif
1065 done=2; }
1066 else
1067 if ( *par!=undefd ) {
1068 # ifdef debug_opti1
1069 printf("*** %i known par #%i of and\n",i,*par);
1070 # endif
1071 /* replace "and adr" with "and #" */
1072 set_absval(p,*par);
1073 opt++;
1074 flag=done=1; }
1075 rega=undefd; }
1076 break; }
1077
1078 case as_ora: {
1079 if ( (*par!=undefd && rega!=undefd) || *par==0xff || rega==0xff ) {
1080 rega|=*par;
1081 # ifdef debug_opti1
1082 printf("*** %i known ora-result #%i\n", i, rega);
1083 # endif
1084 /* replace "ora adr" with "lda #" */
1085 set_absval(p,rega);
1086 p->tok=as_lda;
1087 p->dep=tok[as_lda].dep; p->flags=tok[as_lda].flags;
1088 opt++;
1089 flag=done=1; }
1090 else {
1091 if ( (*par==0) && (p->feeds&reg_sr)==0 ) {
1092 # ifdef debug_opti1
1093 printf("*** %i redundant ora\n",i);
1094 # endif
1095 done=2; }
1096 else
1097 if ( *par!=undefd ) {
1098 # ifdef debug_opti1
1099 printf("*** %i known par #%i of ora\n",i,*par);
1100 # endif
1101 /* replace "ora adr" with "ora #" */
1102 set_absval(p,*par);
1103 opt++;
1104 flag=done=1; }
1105 rega=undefd; }
1106 break; }
1107
1108 case as_eor: {
1109 if ( *par!=undefd && rega!=undefd ) {
1110 rega^=*par;
1111 # ifdef debug_opti1
1112 printf("*** %i known eor-result #%i\n", i, rega);
1113 # endif
1114 /* replace "eor adr" with "lda #" */
1115 set_absval(p,rega);
1116 p->tok=as_lda;
1117 p->dep=tok[as_lda].dep; p->flags=tok[as_lda].flags;
1118 opt++;
1119 flag=done=1; }
1120 else {
1121 if ( (*par==0) && (p->feeds&reg_sr)==0 ) {
1122 # ifdef debug_opti1
1123 printf("*** %i redundant eor\n",i);
1124 # endif
1125 done=2; }
1126 else
1127 if ( *par!=undefd ) {
1128 # ifdef debug_opti1
1129 printf("*** %i known par #%i of eor\n",i,*par);
1130 # endif
1131 /* replace "eor adr" with "eor #" */
1132 set_absval(p,*par);
1133 opt++;
1134 flag=done=1; }
1135 rega=undefd; }
1136 break; }
1137
1138 case as_lda: {
1139 if (*par!=undefd) {
1140 # ifdef debug_opti1
1141 printf("*** %i lda #%i\n",i,*par);
1142 # endif
1143 /* replace "lda adr" with "lda #" */
1144 set_absval(p,*par);
1145 flag=1;
1146 opt++; }
1147 rega=*par;
1148 done=1;
1149 break; }
1150
1151 case as_adc: {
1152 if (*par!=undefd) {
1153 # ifdef debug_opti1
1154 printf("*** %i adc #%i\n",i,*par);
1155 # endif
1156 /* replace "adc adr" with "adc #" */
1157 set_absval(p,*par);
1158 opt++;
1159 flag=1; }
1160 rega=undefd;
1161 done=1;
1162 break; }
1163
1164 case as_sbc: {
1165 if (*par!=undefd) {
1166 # ifdef debug_opti1
1167 printf("*** %i sbc #%i\n",i,*par);
1168 # endif
1169 /* replace "sbc adr" with "sbc #" */
1170 set_absval(p,*par);
1171 opt++;
1172 flag=1; }
1173 rega=undefd;
1174 done=1;
1175 break; }
1176
1177 case as_cmp: {
1178 if (*par!=undefd) {
1179 # ifdef debug_opti1
1180 printf("*** %i cmp #%i\n",i,*par);
1181 # endif
1182 /* replace "cmp adr" with "cmp #" */
1183 set_absval(p,*par);
1184 opt++;
1185 flag=1; }
1186 done=1;
1187 break; }
1188
1189 case as_cpx: {
1190 if (*par!=undefd) {
1191 # ifdef debug_opti1
1192 printf("*** %i cpx #%i\n",i,*par);
1193 # endif
1194 /* replace "cpx adr" with "cpx #" */
1195 set_absval(p,*par);
1196 opt++;
1197 flag=1; }
1198 done=1;
1199 break; }
1200
1201 case as_cpy: {
1202 if (*par!=undefd) {
1203 # ifdef debug_opti1
1204 printf("*** %i cpy #%i\n",i,*par);
1205 # endif
1206 /* replace "cpy adr" with "cpy #" */
1207 set_absval(p,*par);
1208 opt++;
1209 flag=1; }
1210 done=1;
1211 break; }
1212
1213 case as_ldx: {
1214 if (*par!=undefd) {
1215 # ifdef debug_opti1
1216 printf("*** %i ldx #%i\n",i,*par);
1217 # endif
1218 /* replace "ldx adr" with "ldx #" */
1219 set_absval(p,*par);
1220 opt++;
1221 flag=1; }
1222 regx=*par;
1223 done=1;
1224 break; }
1225
1226 case as_ldy: {
1227 if (*par!=undefd) {
1228 # ifdef debug_opti1
1229 printf("*** %i ldy #%i\n",i,*par);
1230 # endif
1231 /* replace "ldy adr" with "ldy #" */
1232 set_absval(p,*par);
1233 opt++;
1234 flag=1; }
1235 regy=*par;
1236 done=1;
1237 break; }
1238 }
1239 }
1240 switch (p->tok) {
1241 case as_inx: { if (regx!=undefd) regx=0xff&(regx+1); done=1; break; }
1242 case as_iny: { if (regy!=undefd) regy=0xff&(regy+1); done=1; break; }
1243 case as_dex: { if (regx!=undefd) regx=0xff&(regx-1); done=1; break; }
1244 case as_dey: { if (regy!=undefd) regy=0xff&(regy-1); done=1; break; }
1245 }
1246
1247 if (i!=j) line_copy(&blkbuf[j],&blkbuf[i]);
1248
1249 if (done==0) {
1250 if ( p->mod & reg_a ) rega=undefd;
1251 if ( p->mod & reg_x ) regx=undefd;
1252 if ( p->mod & reg_y ) regy=undefd;
1253 if ( p->depind & p->mod & mem ) mpar_flag[p->mpar]=undefd;
1254 j++; }
1255 else { if (done==2) { opt++; flag=1; } else j++; }
1256
1257 i++; }
1258
1259 blkbuf_len=j;
1260 return (flag);
1261 }
1262
1263 /*********************************************************************/
1264
1265 int changeable(int aa, int bb)
1266 {
1267 /* check if commands a,b can be exchanged */
1268 /* (no check of fixed-flags !) */
1269
1270 line *a,*b;
1271
1272 # ifdef debug
1273 printf("check %i,%i :",aa,bb);
1274 # endif
1275
1276 a=&blkbuf[aa]; b=&blkbuf[bb];
1277
1278 if (a->feeds & b->dep & valid_map) { dbmsg("no\n"); return 0; }
1279 if (a->mod & b->feeds & valid_map) { dbmsg("no\n"); return 0; }
1280 if (a->dep & b->mod & valid_map ) { dbmsg("no\n"); return 0; }
1281
1282 if ((a->par!= b->par) || (a->par==no_par)) { dbmsg("yes\n"); return 1; }
1283
1284 if (a->mod & b->dep) { dbmsg("no\n"); return 0; }
1285 if (a->mod & b->mod) { dbmsg("no\n"); return 0; }
1286 if (a->dep & b->mod) { dbmsg("no\n"); return 0; }
1287
1288 dbmsg("yes\n");
1289 return 1;
1290 }
1291
1292 int no_dep(int a, int b, int map)
1293 {
1294 while (a<b) {
1295 if ( (blkbuf[a].dep & map) ) return 0;
1296 a++; }
1297 return 1;
1298 }
1299
1300 /*********************************************************************/
1301
1302 void repl1(int i, int j, int parsrc, int newtok)
1303 {
1304 int x;
1305 line *lj, *lparsrc;
1306
1307 if (test_match) return;
1308
1309 lj=&blkbuf[j];
1310 lparsrc=&blkbuf[parsrc];
1311
1312 lj->tok =newtok;
1313 lj->dep =tok[newtok].dep | (lparsrc->depind & valid_map);
1314 lj->depind =lparsrc->depind;
1315 lj->mod =tok[newtok].mod;
1316 lj->flags =tok[newtok].flags;
1317 lj->par =lparsrc->par;
1318 lj->mpar =lparsrc->mpar;
1319 lj->mparhi =lparsrc->mparhi;
1320
1321 # ifdef debug
1322 printf("erase line %i, replace line %i with...\n",i,j);
1323 lineout(&blkbuf[j]);
1324 # endif
1325
1326 x=i;
1327 while( x<blkbuf_len ) {
1328 line_copy(&blkbuf[x],&blkbuf[x+1]);
1329 x++; }
1330
1331 blkbuf_len--;
1332 opt++;
1333 }
1334
1335 void set_tcom(int j, int com)
1336 {
1337 line *lj;
1338
1339 if (test_match) return;
1340
1341 lj=&blkbuf[j];
1342
1343 lj->tok =com;
1344 lj->dep =tok[com].dep;
1345 lj->mod =tok[com].mod;
1346 lj->depind =0;
1347 lj->flags =tok[com].flags;
1348 lj->par =no_par;
1349 opt++;
1350 }
1351
1352 /****************************************************************************/
1353
1354 int add_dep(line *p, int hlp, int map)
1355 {
1356 hlp=((hlp & ( ~p->mod )) | p->dep) & valid_map;
1357
1358 if (p->depind & mem) {
1359
1360 if (p->depind & imem) {
1361
1362 /* dep: ptr,ptr+1 */
1363
1364 mpar_flag[p->mpar]|=map;
1365 mpar_flag[p->mparhi]|=map;
1366
1367 if (p->dep&mem) hlp|=imem; }
1368
1369 else if (p->depind & (reg_x|reg_y) ) {
1370
1371 /* dep: ptr */
1372
1373 mpar_flag[p->mpar]|=map;
1374
1375 if (p->dep&mem) hlp|=imem; }
1376
1377 else
1378
1379 /* normal addressed memory (direct) */
1380
1381 if ( mpar_flag[p->mpar]!=0 && (p->mod & mem)!=0 ) mpar_flag[p->mpar]&=~map;
1382 if (p->dep & mem) mpar_flag[p->mpar]|=map;
1383 }
1384
1385 return hlp;
1386 }
1387
1388 #ifdef debug_opti2
1389
1390 void reglistout(int map)
1391 {
1392 int i;
1393 i=0;
1394 while (i<mpar_num) {
1395 if (mpar_flag[i]&map) printf("%s ",&mparbuf[mpar_pos[i]]);
1396 i++; }
1397 }
1398
1399 #endif
1400
1401 int try_sim2(int i, int j)
1402 {
1403 int j_end,x,y;
1404 int A_dep,A_mod,A_feeds,rest_dep;
1405 int B_dep,B_mod,Brest_dep;
1406
1407 /* the block boundarys of the first one (A) are known [i+1,...,j-1] */
1408 /* calculate A.dep, A.mod and A.feeds */
1409
1410 x=0;
1411 while (x<mpar_num)
1412 {
1413 mpar_flag[x++]=1; /* all mpar used later */
1414 }
1415
1416 rest_dep=blk_mod|imem;
1417
1418 x=blkbuf_len-1;
1419 while (x>=j)
1420 {
1421 rest_dep=add_dep(&blkbuf[x--],rest_dep,1);
1422 }
1423
1424 A_dep=0;
1425 while (x>i)
1426 {
1427 A_dep=add_dep(&blkbuf[x--],A_dep,4);
1428 }
1429
1430 A_mod=0;
1431 x=j-1;
1432 while (x>i)
1433 {
1434 A_mod|=blkbuf[x].mod;
1435 if( (blkbuf[x].depind & mem)!=0 && (blkbuf[x].mod & mem)!=0 )
1436 {
1437 if (blkbuf[x].depind&(imem|reg_x|reg_y))
1438 {
1439 A_mod|=imem;
1440 }
1441 else
1442 {
1443 mpar_flag[blkbuf[x].mpar]|=8;
1444 if (mpar_flag[blkbuf[x].mpar]&1) mpar_flag[blkbuf[x].mpar]|=2;
1445 }
1446 }
1447 x--;
1448 }
1449 A_mod&=valid_map|imem;
1450
1451 A_feeds=rest_dep & A_mod & (valid_map|imem);
1452
1453 #ifdef debug_opti2
1454
1455 printf("BLOCK A-summaries :");
1456 printf("\n A.dep="); mapout(A_dep);
1457 printf("\n "); reglistout(4);
1458 printf("\n A.mod="); mapout(A_mod);
1459 printf("\n "); reglistout(8);
1460 printf("\n A.feed="); mapout(A_feeds);
1461 printf("\n "); reglistout(2);
1462 printf("\n r_dep="); mapout(rest_dep);
1463 printf("\n "); reglistout(1);
1464 printf("\n");
1465
1466 #endif
1467
1468 /* now try to find end of block B */
1469
1470 /* 1) B_mod must not match A_dep */
1471
1472 j_end=j+1;
1473 while (j_end<blkbuf_len)
1474 {
1475 if (blkbuf[j_end].mod & A_dep) break;
1476
1477 if( (blkbuf[j_end].depind & mem)!=0 && (blkbuf[j_end].mod & mem)!=0 )
1478 {
1479 if ((blkbuf[j_end].depind&(imem|reg_x|reg_y))!=0 && (A_dep&imem)!=0) break;
1480 else
1481 if (mpar_flag[blkbuf[j_end].mpar]&4) break;
1482 }
1483 j_end++;
1484 }
1485
1486 # ifdef debug_opti2
1487 printf("found j_end_max=%i\n",j_end);
1488 # endif
1489
1490 while (j_end>j+1)
1491 {
1492
1493 /* 2) calculate Brest_dep, B_mod (B_feeds must not match A_mod) */
1494
1495 x=0;
1496 while (x<mpar_num)
1497 {
1498 mpar_flag[x]=(mpar_flag[x]&15)|16; /* all mpar used later */
1499 x++;
1500 }
1501
1502 Brest_dep=blk_mod|imem;
1503
1504 x=blkbuf_len-1;
1505 while (x>=j_end) Brest_dep=add_dep(&blkbuf[x--],Brest_dep,16);
1506
1507 B_mod=0; y=0; /* y used as flag */
1508 x=j_end-1;
1509 while (x>=j && y==0)
1510 {
1511 B_mod|=blkbuf[x].mod;
1512 if( (blkbuf[x].depind & mem)!=0 && (blkbuf[x].mod & mem)!=0 )
1513 {
1514 if (blkbuf[x].depind&(imem|reg_x|reg_y)) B_mod|=imem;
1515 else
1516 {
1517 if ( (mpar_flag[blkbuf[x].mpar]&4)!=0 )
1518 {
1519 y=1;
1520 continue;
1521 } /* B_mod matched A_dep */
1522 if ( (mpar_flag[blkbuf[x].mpar]&(16|8))==(16|8) )
1523 {
1524 y=1;
1525 continue;
1526 } /* B_feeds matched A_mod */
1527 }
1528 }
1529 x--;
1530 }
1531
1532 if (y)
1533 {
1534 j_end--;
1535 continue;
1536 }
1537
1538 B_mod&=valid_map|imem;
1539
1540 #ifdef debug
1541 printf("Brest_dep = ");
1542 mapout(Brest_dep);
1543 printf("\n");
1544 printf("B_mod = ");
1545 mapout(B_mod);
1546 printf("\n");
1547 #endif
1548
1549 if (Brest_dep & B_mod & A_mod)
1550 {
1551 j_end--;
1552 continue;
1553 }; /* B_feeds matches A_mod so skip */
1554
1555 /* 1) B_mod must not match A_dep */
1556
1557 if (B_mod & A_dep)
1558 {
1559 j_end--;
1560 continue;
1561 }
1562
1563 /* 3) A_feeds not in B_dep */
1564
1565 B_dep=0;
1566 x=j_end-1;
1567 while (x>=j) B_dep=add_dep(&blkbuf[x--],B_dep,32);
1568
1569 if (B_dep & A_feeds & (valid_map|imem))
1570 {
1571 j_end--;
1572 continue;
1573 }
1574
1575 x=0;
1576 while (x<mpar_num && (mpar_flag[x]&(2|32))!=(2|32) ) x++;
1577 if (x!=mpar_num)
1578 {
1579 j_end--;
1580 continue;
1581 }
1582
1583 break;
1584
1585 }
1586
1587 # ifdef debug_opti2
1588 printf("j_end is %i\n\n",j_end);
1589 # endif
1590
1591 if (j_end>=blkbuf_len)
1592 {
1593 dbmsg("### no need to move\n");
1594 return 0;
1595 }
1596
1597 if (j_end<=j+1)
1598 {
1599 dbmsg("### to small to move\n");
1600 return 0;
1601 }
1602
1603 x=j_end-j-1;
1604 while (x>=0)
1605 {
1606 iline_copy(blkbuf_len+x, j+x);
1607 x--;
1608 }
1609 x=j-i-2;
1610 y=i+(j_end-j)+1;
1611 while (x>=0)
1612 {
1613 iline_copy(y+x, i+1+x);
1614 x--;
1615 }
1616 x=j_end-j-1;
1617 while (x>=0)
1618 {
1619 iline_copy(i+1+x, blkbuf_len+x);
1620 x--;
1621 }
1622 return 1;
1623
1624 }
1625
1626 int opti2()
1627 {
1628 int i,j;
1629 int flag;
1630 line *tmp,*il,*jl;
1631
1632 /* Search for "sta tmp,...,lda tmp" and try to simplify */
1633
1634 tmp=&blkbuf[blkbuf_len];
1635 test_match=0;
1636
1637 /* first move all "cl/se ldy #,iny,dey" up as much as possible */
1638
1639 i=0;
1640 while (i<blkbuf_len)
1641 {
1642 if (blkbuf[i].flags & isinit)
1643 {
1644 if ( blkbuf[i].tok==as_ldy && (blkbuf[i].depind & mem)!=0 )
1645 {
1646 i++;
1647 continue;
1648 }
1649 j=i-1;
1650 while (j>=0 && changeable(j,j+1))
1651 {
1652 il=&blkbuf[j+1];
1653 jl=&blkbuf[j--];
1654 line_copy(tmp,il);
1655 line_copy(il,jl);
1656 line_copy(jl,tmp);
1657 }
1658 }
1659 i++;
1660 }
1661
1662 make_feedlist();
1663
1664 /* search for "sta tmp,lda tmp" or "tax,txa" */
1665
1666 i=0;
1667 while (i<blkbuf_len) {
1668 if (blkbuf[i].tok==as_sta && (blkbuf[i].depind&(reg_x|reg_y))==0) {
1669 j=i+1;
1670 while (j<blkbuf_len) {
1671 if (blkbuf[j].par==blkbuf[i].par && blkbuf[j].tok==as_lda) {
1672 # ifdef debug
1673 printf("### found sta/lda at %i/%i\n",i,j);
1674 # endif
1675 if (try_sim2(i,j)) return 1; }
1676 else if (blkbuf[j].par==blkbuf[i].par) break;
1677 j++; }
1678 }
1679
1680 if (blkbuf[i].tok==as_tax) {
1681 j=i+1;
1682 while (j<blkbuf_len) {
1683 if (blkbuf[j].tok==as_txa) {
1684 # ifdef debug
1685 printf("### found tax/txa at %i/%i\n",i,j);
1686 # endif
1687 if (try_sim2(i,j)) return 1; }
1688 else if (blkbuf[j].dep&reg_x) break;
1689 j++; }
1690 }
1691
1692 i++; }
1693
1694 /* so, can't move blocks but may be we can use registers
1695 istead of tmpxx ? */
1696
1697 /* first move all "ldy #" down as much as possible */
1698
1699 i=0;
1700 while (i<blkbuf_len) {
1701 if (blkbuf[i].tok==as_ldy && (blkbuf[i].depind&mem)==0) {
1702 j=i;
1703 while (j<blkbuf_len-1 && changeable(j,j+1)) {
1704 il=&blkbuf[j+1];
1705 jl=&blkbuf[j++];
1706 line_copy(tmp,il);
1707 line_copy(il,jl);
1708 line_copy(jl,tmp); } }
1709 i++; }
1710
1711 make_feedlist();
1712
1713 i=0;
1714 while (i<blkbuf_len) {
1715 if (blkbuf[i].tok==as_sta && (blkbuf[i].depind&(reg_x|reg_y))==0) {
1716 j=i+1; flag=blkbuf[i].passes;
1717 while (j<blkbuf_len) {
1718 flag|=blkbuf[j].mod|blkbuf[j].dep;
1719 if (blkbuf[j].par==blkbuf[i].par && blkbuf[j].tok==as_lda && (blkbuf[j].passes & mem)==0 ) {
1720 # ifdef debug
1721 printf("### again sta/lda at %i/%i\n",i,j);
1722 # endif
1723 /* if y or x unused inbetween, then replace */
1724 if ( (flag & reg_y)==0 ) {
1725 dbmsg("*** replace sta,lda -> tay,tya\n");
1726 set_tcom(i,as_tay); set_tcom(j,as_tya);
1727 return 1; }
1728 if ( (flag & reg_x)==0 ) {
1729 dbmsg("*** replace sta,lda -> tax,txa\n");
1730 set_tcom(i,as_tax); set_tcom(j,as_txa);
1731 return 1; } }
1732 else if (blkbuf[j].par==blkbuf[i].par) break;
1733 j++; }
1734 }
1735 i++; }
1736
1737 return 0;
1738 }
1739
1740 /****************************************************************************/
1741
1742 int com_match2_default(int j)
1743 {
1744 if ( (com_match_lptr->flags & dupl)==0 && \
1745 com_match_lptr->tok==blkbuf[j].tok && \
1746 com_match_lptr->par==blkbuf[j].par ) {
1747 op2msg("duplicated command\n");
1748 repl1(com_match_lnum,j,com_match_lnum,com_match_lptr->tok);
1749 return 1; }
1750
1751 return 0;
1752 }
1753
1754 int com_match2_tax(int j)
1755 {
1756 line *b;
1757 b=&blkbuf[j];
1758
1759 if (b->tok==as_txa) {
1760 op2msg("tax,txa -> tax\n");
1761 repl1(com_match_lnum,j,com_match_lnum,as_tax);
1762 return 1; }
1763
1764 if (b->tok==as_stx && (b->passes & reg_x)==0) {
1765 if (!no_dep(com_match_lnum,j,reg_x)) return 0;
1766 op2msg("tax,stx -> sta\n");
1767 repl1(com_match_lnum,j,j,as_sta);
1768 return 1; }
1769
1770 return com_match2_default(j);
1771 }
1772
1773 int com_match2_txa(int j)
1774 {
1775 line *b;
1776 b=&blkbuf[j];
1777
1778 if (b->tok==as_tax) {
1779 op2msg("txa,tax -> txa\n");
1780 repl1(com_match_lnum,j,com_match_lnum,as_txa);
1781 return 1; }
1782
1783 if ( b->tok==as_sta && (b->dep&(reg_x|reg_y))==0 && (b->passes & reg_a)==0 ) {
1784 if (!no_dep(com_match_lnum,j,reg_a)) return 0;
1785 op2msg("txa,sta -> stx\n");
1786 repl1(com_match_lnum,j,j,as_stx);
1787 return 1; }
1788
1789 return com_match2_default(j);
1790 }
1791
1792 int com_match2_tay(int j)
1793 {
1794 line *b;
1795 b=&blkbuf[j];
1796
1797 if (b->tok==as_tya) {
1798 op2msg("tay,tya -> tay\n");
1799 repl1(com_match_lnum,j,com_match_lnum,as_tay);
1800 return 1; }
1801
1802 if (b->tok==as_sty && (b->passes & reg_y)==0) {
1803 if (!no_dep(com_match_lnum,j,reg_y)) return 0;
1804 op2msg("tay,sty -> sta\n");
1805 repl1(com_match_lnum,j,j,as_sta);
1806 return 1; }
1807
1808 return com_match2_default(j);
1809 }
1810
1811 int com_match2_tya(int j)
1812 {
1813 line *b;
1814 b=&blkbuf[j];
1815
1816 if (b->tok==as_tay) {
1817 op2msg("tya,tay -> tya\n");
1818 repl1(com_match_lnum,j,com_match_lnum,as_tya);
1819 return 1; }
1820
1821 if ( b->tok==as_sta && (b->dep&(reg_x|reg_y))==0 && (b->passes & reg_a)==0 ) {
1822 if (!no_dep(com_match_lnum,j,reg_a)) return 0;
1823 op2msg("tya,sta -> sty\n");
1824 repl1(com_match_lnum,j,j,as_sty);
1825 return 1; }
1826
1827 return com_match2_default(j);
1828 }
1829
1830 int com_match2_txs(int j)
1831 {
1832 if (blkbuf[j].tok==as_tsx) {
1833 op2msg("txs,tsx -> txs\n");
1834 repl1(com_match_lnum,j,com_match_lnum,as_txs);
1835 return 1; }
1836
1837 return com_match2_default(j);
1838 }
1839
1840 int com_match2_tsx(int j)
1841 {
1842 if (blkbuf[j].tok==as_txs) {
1843 op2msg("tsx,txs -> tsx\n");
1844 repl1(com_match_lnum,j,com_match_lnum,as_tsx);
1845 return 1; }
1846
1847 return com_match2_default(j);
1848 }
1849
1850 int com_match2_lda(int j)
1851 {
1852 line *b;
1853 b=&blkbuf[j];
1854
1855 if ( (b->passes & reg_a)==0 && (com_match_lptr->dep&(reg_x|reg_y))==0 ) {
1856 if (b->tok==as_tax) {
1857 if (!no_dep(com_match_lnum,j,reg_a)) return 0;
1858 op2msg("lda,tax -> ldx\n");
1859 repl1(com_match_lnum,j,com_match_lnum,as_ldx);
1860 return 1; }
1861 if (b->tok==as_tay) {
1862 if (!no_dep(com_match_lnum,j,reg_a)) return 0;
1863 op2msg("lda,tay -> ldy\n");
1864 repl1(com_match_lnum,j,com_match_lnum,as_ldy);
1865 return 1; }
1866 }
1867
1868 if ( b->tok==as_sta && com_match_lptr->par==blkbuf[j].par ) {
1869 op2msg("lda,sta -> lda\n");
1870 repl1(com_match_lnum,j,com_match_lnum,as_lda);
1871 return 1; }
1872
1873 return com_match2_default(j);
1874 }
1875
1876 int com_match2_ldx(int j)
1877 {
1878 line *b;
1879 b=&blkbuf[j];
1880
1881 if (b->tok==as_txa && (b->passes & reg_x)==0) {
1882 if (!no_dep(com_match_lnum,j,reg_x)) return 0;
1883 op2msg("ldx,txa -> lda\n");
1884 repl1(com_match_lnum,j,com_match_lnum,as_lda);
1885 return 1; }
1886
1887 if ( b->tok==as_stx && com_match_lptr->par==b->par ) {
1888 op2msg("ldx,stx -> ldx\n");
1889 repl1(com_match_lnum,j,com_match_lnum,as_ldx);
1890 return 1; }
1891
1892 return com_match2_default(j);
1893 }
1894
1895 int com_match2_ldy(int j)
1896 {
1897 line *b;
1898 b=&blkbuf[j];
1899
1900 if (b->tok==as_tya && (b->passes & reg_y)==0) {
1901 if (!no_dep(com_match_lnum,j,reg_y)) return 0;
1902 op2msg("ldy,tya -> lda\n");
1903 repl1(com_match_lnum,j,com_match_lnum,as_lda);
1904 return 1; }
1905
1906 if ( b->tok==as_sty && com_match_lptr->par==b->par ) {
1907 op2msg("ldy,sty -> ldy\n");
1908 repl1(com_match_lnum,j,com_match_lnum,as_ldy);
1909 return 1; }
1910
1911 return com_match2_default(j);
1912 }
1913
1914 int com_match2_sta(int j)
1915 {
1916 line *b;
1917 b=&blkbuf[j];
1918
1919 if (com_match_lptr->par==b->par) {
1920 if (b->tok==as_lda) {
1921 op2msg("sta,lda -> sta\n");
1922 repl1(com_match_lnum,j,com_match_lnum,as_sta);
1923 return 1; }
1924 if (b->tok==as_ldx) {
1925 op2msg("sta,ldx -> sta,tax\n");
1926 set_tcom(j,as_tax);
1927 return 1; }
1928 if (b->tok==as_ldy) {
1929 op2msg("sta,ldy -> sta,tay\n");
1930 set_tcom(j,as_tay);
1931 return 1; }
1932 }
1933
1934 return com_match2_default(j);
1935 }
1936
1937 int com_match2_stx(int j)
1938 {
1939 line *b;
1940 b=&blkbuf[j];
1941
1942 if (com_match_lptr->par==b->par) {
1943 if (b->tok==as_ldx) {
1944 op2msg("stx,ldx -> stx\n");
1945 repl1(com_match_lnum,j,com_match_lnum,as_stx);
1946 return 1; }
1947 if (b->tok==as_lda) {
1948 op2msg("stx,lda -> stx,txa\n");
1949 set_tcom(j,as_txa);
1950 return 1; }
1951 }
1952
1953 return com_match2_default(j);
1954 }
1955
1956 int com_match2_sty(int j)
1957 {
1958 line *b;
1959 b=&blkbuf[j];
1960
1961 if (com_match_lptr->par==b->par) {
1962 if (b->tok==as_ldy) {
1963 op2msg("sty,ldy -> sty\n");
1964 repl1(com_match_lnum,j,com_match_lnum,as_sty);
1965 return 1; }
1966 if (b->tok==as_lda) {
1967 op2msg("sty,lda -> sty,tya\n");
1968 set_tcom(j,as_tya);
1969 return 1; }
1970 }
1971
1972 return com_match2_default(j);
1973 }
1974
1975 /****************************************************************************/
1976
1977 int (*com_match1(int i))()
1978 {
1979 /* find match for first command (of two) and return pointer to com_match2-function */
1980
1981 dbmsg("com_match1\n");
1982
1983 com_match_lnum=i;
1984 com_match_lptr=&blkbuf[i];
1985
1986 switch (com_match_lptr->tok) {
1987 case as_tax: return com_match2_tax;
1988 case as_txa: return com_match2_txa;
1989 case as_tay: return com_match2_tay;
1990 case as_tya: return com_match2_tya;
1991 case as_txs: return com_match2_txs;
1992 case as_tsx: return com_match2_tsx;
1993 case as_lda: return com_match2_lda;
1994 case as_ldx: return com_match2_ldx;
1995 case as_ldy: return com_match2_ldy;
1996 case as_sta: return com_match2_sta;
1997 case as_stx: return com_match2_stx;
1998 case as_sty: return com_match2_sty;
1999 default: return com_match2_default;
2000 }
2001 return NULL;
2002 }
2003
2004 int opti3()
2005 {
2006 static int i,j,x,y;
2007 static int (*com_match2)();
2008 static line *il,*jl,*tmp;
2009
2010 tmp=&blkbuf[blkbuf_len];
2011
2012 i=0;
2013 while (i<blkbuf_len-1) {
2014 test_match=0;
2015 com_match2=com_match1(i);
2016 if (com_match2==NULL || (blkbuf[i].flags & fixed)!=0 ) { i++; continue; }
2017 j=i+1;
2018 while (j<blkbuf_len) {
2019 if (blkbuf[j].flags & fixed) break; /* don't move through fixed items */
2020 # ifdef debug
2021 printf("o+: %i,%i ?\n",i,j);
2022 # endif
2023 if (com_match2(j)) return 1;
2024 if (!changeable(i,j)) break;
2025 j++; }
2026 x=j+1;
2027 test_match=1;
2028 while (x<blkbuf_len) {
2029 if (blkbuf[j].flags & fixed) break; /* don't move through fixed items */
2030 # ifdef debug
2031 printf("o-: %i,%i\n",i,x);
2032 # endif
2033 if (!com_match2(x)) { x++; continue; }
2034 y=x-1;
2035 while (y>j && changeable(y,x)) y--;
2036 if (y==j && changeable(y,x)) {
2037 /* move x upwards to position j */
2038 y=x-1;
2039 while (y>=j) {
2040 il=&blkbuf[y];
2041 jl=&blkbuf[y+1];
2042 line_copy(tmp,il);
2043 line_copy(il,jl);
2044 line_copy(jl,tmp);
2045 y--; }
2046 test_match=0;
2047 com_match2(j);
2048 return 1; }
2049 x++; }
2050 i++; }
2051
2052 return 0;
2053 }
2054
2055 /*********************************************************************/
2056
2057 void add_line(line *p)
2058 {
2059 if (blkbuf_len+1==blkbuf_max) {
2060 printf("error: block-buffer overrun\n");
2061 exit(1); }
2062 if (blkbuf_len==0) was_line=inp_line;
2063 line_copy(&blkbuf[blkbuf_len],p);
2064 blkbuf_len++;
2065
2066 # ifdef debug_parse
2067 printf("line %i added tok=%i\n",blkbuf_len-1,blkbuf[blkbuf_len-1]);
2068 # endif
2069 }
2070
2071 void optimize_block()
2072 {
2073 if (blkbuf_len<1) return;
2074
2075 dbmsg("<BLOCK>\n");
2076
2077 opt=0;
2078
2079 while (1) {
2080 make_feedlist();
2081
2082 # ifdef debug
2083 i=0;
2084 while (i<blkbuf_len) {
2085 printf("%3i:",i);
2086 lineout(&blkbuf[i]);
2087 i++; }
2088 # endif
2089
2090 dbmsg("simple...\n");
2091 if (simple_erase()) continue;
2092
2093 dbmsg("opti1...\n");
2094 if (opti1()) continue;
2095
2096 dbmsg("opti2...\n");
2097 if (opti2()) continue;
2098
2099 dbmsg("opti3...\n");
2100 if (opti3()) continue;
2101
2102 break;
2103 }
2104
2105 # ifdef debug
2106 printf("<result>\n");
2107 i=0;
2108 while (i<blkbuf_len) {
2109 printf("%3i ",i);
2110 lineout(&blkbuf[i]);
2111 i++; }
2112 # endif
2113
2114 printf("\n");
2115 if (opt!=0) printf(" ; REMOVED %i was line %i\n",opt,was_line);
2116 bufout();
2117 printf("\n");
2118
2119 blkbuf_len=0; /* erase block-buffer */
2120 }
2121
2122 /*********************************************************************/
2123
2124 int main(int argc, char **argv)
2125 {
2126 char linebuf[line_len];
2127 line tmp;
2128 int ret;
2129 FILE *fin;
2130 int i;
2131 int wall_flag;
2132
2133 if (argc<2) how_to();
2134 fin=fopen(argv[1],"r");
2135 if (fin==NULL) { printf("can't open file\n"); exit(1); }
2136
2137 par_used=0;
2138 par_num=0;
2139 blkbuf_len=0;
2140 wall_flag=0;
2141 inp_line=0;
2142
2143 while(readline(linebuf,fin)!=EOF) {
2144
2145 i=nextchar(linebuf,0);
2146 if (linebuf[i]=='u' && linebuf[i+1]=='s' && linebuf[i+2]=='e') {
2147
2148 /* read blk_mod from input-line */
2149 i=nextchar(linebuf,i+3);
2150 blk_mod=0;
2151 while (linebuf[i]!='\0') {
2152 switch (linebuf[i]) {
2153 case 'a': { wall_flag=reg_a; break; }
2154 case 'x': { wall_flag=reg_x; break; }
2155 case 'y': { wall_flag=reg_y; break; }
2156 case 'n': { wall_flag=flag_n; break; }
2157 case 'z': { wall_flag=flag_z; break; }
2158 case 'v': { wall_flag=flag_v; break; }
2159 case 'c': { wall_flag=flag_c; break; }
2160 case 'd': { wall_flag=flag_d; break; }
2161 case 'i': { wall_flag=flag_i; break; }
2162 default : {
2163 printf(" error: unknown flag/register \"%c\"\n",linebuf[i]); exit(1); }
2164 }
2165 blk_mod|=wall_flag;
2166 i=nextchar(linebuf,i+1); }
2167
2168 wall_flag=1;
2169 continue; }
2170
2171 ret=parse_line(linebuf, &tmp);
2172
2173 if (ret!=0) {
2174 if (!wall_flag) blk_mod=valid_map;
2175 optimize_block();
2176 wall_flag=0;
2177 if ( tmp.tok==no_tok || ret>1 || (tmp.flags & isjmp)!=0 ) { clear_buf(); puts(linebuf); }
2178 else { /* only print label */
2179 i=nextchar(linebuf,0);
2180 while ( linebuf[i]!='\0' && linebuf[i]!=' ' && linebuf[i]!='\t' )
2181 putc(linebuf[i++],stdout);
2182 printf("\n");
2183 if (tmp.tok!=null_tok) add_line(&tmp); }
2184 continue; }
2185
2186 if (tmp.tok==null_tok) {
2187 # ifdef debug_parse
2188 puts(linebuf);
2189 # endif
2190 continue; }
2191
2192 if ( tmp.tok==no_tok || (tmp.flags & isjmp)!=0 ) {
2193 if (!wall_flag) blk_mod=valid_map;
2194 optimize_block();
2195 puts(linebuf);
2196 clear_buf(); }
2197 else { if (tmp.tok==as_jsr) printf("argh!");
2198 add_line(&tmp); }
2199 wall_flag=0;
2200 }
2201
2202 fclose(fin);
2203 return 0;
2204 }

  ViewVC Help
Powered by ViewVC 1.1.26