2 * Peephole Optimizer for the C Minus32 386 compiler.
\r
4 * The strategy behind the peephole optimizer is to keep the peephole
\r
5 * buffer completly filled. The list of optimizations is in priority order
\r
6 * in the table below. Each buffer full is checked against each entry
\r
7 * in the table. Even after a substitution is made, the new substituted
\r
8 * code is left in the buffer to check for further optimization.
\r
9 * See the rules for table entries
\r
10 * just prior to the table below. All entries are searched even after
\r
11 * new code is inserted to ensure all optimization sequences used.
\r
13 * Copyright 1990 Dave Dunfield
\r
14 * Copyright 1992 R.A. Burgess
\r
21 #define OBUF_SIZE 10 /* number of entries in peephole buffer */
\r
22 #define OLINE_SIZE 100 /* maximum size of input line */
\r
23 #define OSYMBOLS 8 /* maximum # symbols per peep */
\r
24 #define OSYMBOL_SIZE 25 /* maximum size of symbol */
\r
27 * Peephole optimization table:
\r
29 * Each two entries represent the instruction sequences:
\r
30 * The first is the string of instructions to SEARCH for,
\r
31 * the second is the optimized REPLACEMENT string.
\r
33 * 1) The REPLACEMENT instructions are in reverse order!
\r
34 * 2) The highest priority entries should be entered first in the table.
\r
35 * 3) Tabs (\t) should begin each entry.
\r
36 * 4) Linefeeds (\n) should end each except for the last entry of a line.
\r
40 char *peep_table[] = {
\r
42 /* 80386/80486 Optimizations */
\r
44 /* data movement & register usage optimizations */
\r
46 "\tMOV \200,\201\n\tMOV \201,\200",
\r
49 "\tMOV \200,\201\n\tMOV \200,\202",
\r
52 "\tMOV \200,\201\n\tMOV \202,\200\n\tMOV \201,\200",
\r
53 "\tMOV \202,\200\n\tMOV \200,\201",
\r
55 "\tMOV EAX,\200\n\tMOV ECX,EAX",
\r
58 "\tMOV ESI,\200\n\tMOV EAX,ESI",
\r
61 "\tLEA ESI,\200\n\tMOV EAX,ESI",
\r
64 "\tPUSH EAX\n\tLEA ESI,\200\n\tMOV EAX,ESI\n\tPOP EBX\n\tADD EAX,EBX",
\r
65 "\tADD EAX,ESI\n\tLEA ESI,\200",
\r
67 "\tPOP EBX\n\tMOV EAX,EBX",
\r
70 /* indexing operations */
\r
72 "\tMOV ECX,32\n\tMUL ECX",
\r
75 "\tMOV ECX,32\n\tIMUL ECX",
\r
78 "\tMOV ECX,16\n\tMUL ECX",
\r
81 "\tMOV ECX,16\n\tIMUL ECX",
\r
84 "\tMOV ECX,8\n\tMUL ECX",
\r
87 "\tMOV ECX,8\n\tIMUL ECX",
\r
90 "\tMOV ECX,4\n\tMUL ECX",
\r
93 "\tMOV ECX,4\n\tIMUL ECX",
\r
96 "\tMOV ECX,2\n\tMUL ECX",
\r
99 "\tMOV ECX,2\n\tIMUL ECX",
\r
102 /* jump optimizations */
\r
104 "\tJMP \200\n\200:",
\r
107 "\tJMP \200\n\201:\n\200:",
\r
110 "\tJMP \200\n\tJMP \201",
\r
113 "\tJNZ \200\n\tJMP \201\n\200:\n\tJMP \202\n\201:",
\r
114 "\201:\n\tJMP \202\n\tJZ \201",
\r
116 "\tJZ \200\n\tJMP \201\n\200:\n\tJMP \202\n\201:",
\r
117 "\201:\n\tJMP \202\n\tJNZ \201",
\r
119 "\tJNZ \200\n\tJMP \201\n\200:\n\tJMP SHORT \202",
\r
120 "\tJMP \201\n\tJNZ \202",
\r
122 "\tJZ \200\n\tJMP \201\n\200:\n\tJMP SHORT \202",
\r
123 "\tJMP \201\n\tJZ \202",
\r
125 /* conversion optimizations */
\r
127 "\tMOV AL,\200\n\tMOVSX EAX,AL",
\r
128 "\tMOVSX EAX,BYTE PTR \200",
\r
130 "\tMOV AL,\200\n\tMOVZX EAX,AL",
\r
131 "\tMOVZX EAX,BYTE PTR \200",
\r
133 "\tMOV AX,\200\n\tMOVSX EAX,AX",
\r
134 "\tMOVSX EAX,WORD PTR \200",
\r
136 "\tMOV AX,\200\n\tMOVZX EAX,AX",
\r
137 "\tMOVZX EAX,WORD PTR \200",
\r
139 /* comparisons to ECX, or MOV into EAX for compare (when not needed) */
\r
141 "\tMOV ECX,\200\n\tCMP EAX,ECX",
\r
144 "\tMOVSX ECX,BYTE PTR\200\n\tCMP EAX,ECX",
\r
145 "\tCMP AL,BYTE PTR\200",
\r
147 "\tMOVZX ECX,BYTE PTR\200\n\tCMP EAX,ECX",
\r
148 "\tCMP AL,BYTE PTR\200",
\r
150 /* stack/parameters */
\r
152 "\tMOV EAX,[\200\n\tPUSH EAX",
\r
153 "\tPUSH DWORD PTR [\200",
\r
155 "\tMOV EAX,\200\n\tPUSH EAX",
\r
158 /* more simple optimizations */
\r
174 /* circular peep hole buffer & read/write pointers */
\r
176 char peep_buffer[OBUF_SIZE][OLINE_SIZE];
\r
178 unsigned peep_top = 0, /* first entry in circular buffer */
\r
179 peep_next = 0; /* Next place to put new entry */
\r
181 /* If ((next+1) mod n entries) == top then buffer is full */
\r
182 /* If next == top then buffer is empty */
\r
186 char symbols[OSYMBOLS][OSYMBOL_SIZE];
\r
188 /* End of Optimize.h */
\r
193 MOV ESI,OFFSET xxxx
\r\r
197 MOV ESI,OFFSET xxxx
\r\r
198 MOV EAX, [ESI+EAX*2]
\r
218 MOVZX EAX,WORD PTR _CrntStrucDef
\r
227 MOVZX EAX,WORD PTR [ESI]
\r
231 MOV EAX,DWORD PTR [ESI]
\r
234 MOV EAX,DWORD PTR [ESI]
\r