Pristine Ack-5.5
[Ack-5.5.git] / mach / pdp / top / table
1 /* PDP-11 desciptor table for ACK target optimizer */
2
3 /* Tunable constants: */
4
5 MAXOP           2;
6 LABEL_STARTER   'I';
7 OPC_TERMINATOR  ' ';
8
9 %%;
10
11 /* useful addressing modes: */
12
13 ZERO            {strcmp(VAL,"$00") == 0                 };
14 ONE             {strcmp(VAL,"$01") == 0                 };
15 CONST           {VAL[0] == '$'                          };      /* constant */
16 A,B             {no_side_effects(VAL)                   };
17 X,Y             {TRUE                                   };
18 REG             {is_register(VAL)                       };      /* register */
19 SREG            {is_scratchreg(VAL)                     };      /* scratch reg */
20 M_ONE           {strcmp(VAL,"$-1") == 0                 };      /* -1   */
21 LAB,L1,L2       {VAL[0] == 'I'                          };      /* label */
22
23 %%;
24
25 /* optimization patterns: */
26
27 add ZERO,A  {carry_dead(REST)}  ->      ;
28 add ONE, X  {carry_dead(REST)}  ->      inc X;
29 sub ONE, X  {carry_dead(REST)}  ->      dec X;
30
31 mov A,A                         ->      tst A;
32
33 /* tst-elimination */
34 tst (sp)+ : tst X               ->      mov X,(sp)+;
35 tst (sp)+ : mov X,-(sp)         ->      mov X,(sp);
36 mov A,X : tst A                 ->      mov A,X;
37 mov X,A : tst A                 ->      mov X,A;
38
39 /* register subsumption */
40 mov REG,A : ANY A,X             ->      mov REG,A : ANY REG,X;
41 mov REG,A : ANY *A              ->      mov REG,A : ANY *REG;
42 mov REG,A : ANY *A,X            ->      mov REG,A : ANY *REG,X;
43 mov REG,A : ANY X,*A            ->      mov REG,A : ANY X,*REG;
44
45 /* compare with -1 */
46 cmp SREG,M_ONE : jeq LAB        ->      inc SREG : jeq LAB;
47 cmp SREG,M_ONE : jne LAB        ->      inc SREG : jne LAB;
48
49 /* skip over jump */
50 jeq L1 : jbr L2: labdef L1      ->      jne L2 : labdef L1;
51 jge L1 : jbr L2: labdef L1      ->      jlt L2 : labdef L1;
52 jgt L1 : jbr L2: labdef L1      ->      jle L2 : labdef L1;
53 jlt L1 : jbr L2: labdef L1      ->      jge L2 : labdef L1;
54 jle L1 : jbr L2: labdef L1      ->      jgt L2 : labdef L1;
55 jne L1 : jbr L2: labdef L1      ->      jeq L2 : labdef L1;
56
57 /* byte-test */
58 clr SREG : bisb X,SREG : tst SREG : jeq LAB
59                                 ->      tstb X : jeq LAB;
60 clr SREG : bisb X,SREG : tst SREG : jne LAB
61                                 ->      tstb X : jne LAB;
62
63 %%;
64
65 /* auxiliary routines: */
66
67 int no_side_effects(s)
68         register char *s;
69 {
70
71         for(;;) {
72                 switch(*s++) {
73                         case '\0': return TRUE;
74                         case '-':  if (*s == '(') return FALSE; break;
75                         case ')':  if (*s == '+') return FALSE; break;
76                 }
77         }
78         /* NOTREACHED */
79 }
80
81 int is_register(s)
82         register char *s;
83 {
84         return *s++ == 'r' && *s >= '0' && *s <= '5';
85 }
86
87 int is_scratchreg(s)
88         register char *s;
89 {
90         return *s++ == 'r' && (*s == '0' || *s == '1' || *s == '3');
91 }
92
93 int carry_dead(s)
94         char *s;
95 {
96         switch(*s++) {
97                 case 'a':       /* adc and adcb */
98                         return *s++ != 'd' || *s != 'c';
99                 case 'b':       /* bcc, bcs, bhi, bhis, blo, blos */
100                         return *s != 'c' && *s != 'h' &&
101                                 (*s++ != 'l' || *s != 'o');
102                 case 's':       /* sbc and sbcb */
103                         return *s++ != 'b' || *s != 'c';
104                 default:
105                         return TRUE;
106         }
107 }