OpenCores
URL https://opencores.org/ocsvn/ao486/ao486/trunk

Subversion Repositories ao486

[/] [ao486/] [trunk/] [ao486_tool/] [src/] [ao486/] [ParseMicrocode.java] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 alfik
/*
2
 * Copyright (c) 2014, Aleksander Osman
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *
8
 * * Redistributions of source code must retain the above copyright notice, this
9
 *   list of conditions and the following disclaimer.
10
 *
11
 * * Redistributions in binary form must reproduce the above copyright notice,
12
 *   this list of conditions and the following disclaimer in the documentation
13
 *   and/or other materials provided with the distribution.
14
 *
15
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
 */
26
 
27
package ao486;
28
 
29
import java.util.HashMap;
30
import java.util.HashSet;
31
import java.util.LinkedList;
32
 
33
public class ParseMicrocode extends Parse {
34
 
35
    ParseMicrocode(HashMap<String, String> defines, StringBuilder build, StringBuilder build_loop) {
36
        this.build      = build;
37
        this.build_loop = build_loop;
38
        this.defines    = defines;
39
    }
40
 
41
    private StringBuilder build;
42
    private StringBuilder build_loop;
43
    private HashMap<String, String> defines;
44
 
45
    static class MicrocodeStep {
46
        String type;
47
        String cmdex;
48
        String cmd;
49
    }
50
 
51
    String parse_cmdex(String cmdex) throws Exception {
52
        if(cmdex.startsWith("CMDEX_") == false) throw new Exception("Invalid cmdex: " + cmdex);
53
        cmdex = cmdex.substring(6);
54
 
55
        //find names (prefixes) to check
56
        LinkedList<String> names = new LinkedList<>();
57
        int index = cmdex.length();
58
        names.add(cmdex.substring(0, index));
59
 
60
        while(true) {
61
            index = cmdex.lastIndexOf("_", index);
62
            if(index != -1) {
63
                names.add(cmdex.substring(0, index));
64
                index--;
65
            }
66
            else break;
67
        }
68
 
69
        String cmd = null;
70
        for(String name : names) {
71
 
72
            if(defines.containsKey("CMD_" + name)) {
73
                cmd = "CMD_" + name;
74
                break;
75
            }
76
        }
77
        if(cmd == null) throw new Exception("CMD for CMDEX not found: CMDEX_" + cmdex);
78
 
79
        return "`" + cmd;
80
    }
81
 
82
    @Override
83
    void parse(String section) throws Exception {
84
        section = section.replaceAll("\\n", " ");
85
        section = section.trim();
86
 
87
        LinkedList<MicrocodeStep> list = new LinkedList<>();
88
 
89
        while(section.length() > 0) {
90
 
91
            if(section.startsWith("`")) {
92
                int index = section.indexOf(" ");
93
                if(index == -1) throw new Exception("Invalid `<token>.");
94
 
95
                String cmdex = section.substring(0, index);
96
                String cmd = parse_cmdex(cmdex.substring(1));
97
 
98
                MicrocodeStep step = new MicrocodeStep();
99
                step.cmd    = cmd;
100
                step.type   = "`";
101
                step.cmdex  = cmdex;
102
 
103
                list.add(step);
104
 
105
                section = section.substring(index+1);
106
            }
107
            else if(section.startsWith("IF(")) {
108
                int index = section.indexOf(");");
109
                if(index == -1) throw new Exception("Invalid IF(<token>);");
110
 
111
                if(section.startsWith("IF(`CMDEX_")) {
112
                    int idx1 = section.indexOf(" ");
113
                    int idx2 = section.indexOf(")");
114
                    int idx = (idx1 < idx2)? idx1 : idx2;
115
                    if(idx1 == -1 || idx2 == -1) throw new Exception("Invalid IF(`<token>);");
116
 
117
                    String cmdex = section.substring(3, idx);
118
                    String cmd   = parse_cmdex(cmdex.substring(1));
119
 
120
                    MicrocodeStep step = new MicrocodeStep();
121
                    step.cmd   = cmd;
122
                    step.type  = "IF";
123
                    step.cmdex = "mc_cmdex_last == " + section.substring(3, index);
124
 
125
                    list.add(step);
126
                }
127
                else {
128
                    MicrocodeStep step = new MicrocodeStep();
129
                    step.cmd   = null;
130
                    step.type  = "IF";
131
                    step.cmdex = section.substring(3, index);
132
 
133
                    list.add(step);
134
                }
135
 
136
                section = section.substring(index+2);
137
            }
138
            else if(section.startsWith("LOOP(")) {
139
                int index = section.indexOf(");");
140
                if(index == -1) throw new Exception("Invalid LOOP(<token>);");
141
 
142
                String cmdex = section.substring(5, index);
143
                String cmd   = parse_cmdex(cmdex.substring(1));
144
 
145
                MicrocodeStep step = new MicrocodeStep();
146
                step.cmd   = cmd;
147
                step.type  = "LOOP";
148
                step.cmdex = cmdex;
149
 
150
                list.add(step);
151
 
152
                section = section.substring(index+2);
153
            }
154
            else if(section.startsWith("CALL(")) {
155
                int index = section.indexOf(");");
156
                if(index == -1) throw new Exception("Invalid CALL(<token>);");
157
 
158
                String cmdex = section.substring(5, index);
159
                String cmd   = parse_cmdex(cmdex.substring(1));
160
 
161
                MicrocodeStep step = new MicrocodeStep();
162
                step.cmd   = cmd;
163
                step.type  = "CALL";
164
                step.cmdex = cmdex;
165
 
166
                list.add(step);
167
 
168
                section = section.substring(index+2);
169
            }
170
            else if(section.startsWith("JMP(")) {
171
                int index = section.indexOf(");");
172
                if(index == -1) throw new Exception("Invalid JMP(<token>);");
173
 
174
                String cmdex = section.substring(4, index);
175
                String cmd   = parse_cmdex(cmdex.substring(1));
176
 
177
                MicrocodeStep step = new MicrocodeStep();
178
                step.cmd   = cmd;
179
                step.type  = "JMP";
180
                step.cmdex = cmdex;
181
 
182
                list.add(step);
183
 
184
                section = section.substring(index+2);
185
            }
186
            else if(section.startsWith("LAST(")) {
187
                int index = section.indexOf(");");
188
                if(index == -1) throw new Exception("Invalid LAST(<token>);");
189
 
190
                String cmdex = section.substring(5, index);
191
                String cmd   = parse_cmdex(cmdex.substring(1));
192
 
193
                MicrocodeStep step = new MicrocodeStep();
194
                step.cmd   = cmd;
195
                step.type  = "LAST";
196
                step.cmdex = cmdex;
197
 
198
                list.add(step);
199
 
200
                section = section.substring(index+2);
201
            }
202
            else if(section.startsWith("LAST_DIRECT(")) {
203
                int index = section.indexOf(",");
204
                if(index == -1) throw new Exception("Invalid LAST_DIRECT(<token>);");
205
 
206
                int end_index = section.indexOf(");");
207
                if(end_index == -1) throw new Exception("Invalid LAST_DIRECT(<token>);");
208
 
209
                MicrocodeStep step = new MicrocodeStep();
210
                step.cmd   = section.substring(12, index);
211
                step.type  = "LAST_DIRECT";
212
                step.cmdex = section.substring(index+1, end_index);
213
 
214
                list.add(step);
215
 
216
                section = section.substring(end_index+2);
217
            }
218
            else if(section.startsWith("DIRECT(")) {
219
                int index = section.indexOf(",");
220
                if(index == -1) throw new Exception("Invalid DIRECT(<token>);");
221
 
222
                int end_index = section.indexOf(");");
223
                if(end_index == -1) throw new Exception("Invalid DIRECT(<token>);");
224
 
225
                MicrocodeStep step = new MicrocodeStep();
226
                step.cmd   = section.substring(7, index);
227
                step.type  = "DIRECT";
228
                step.cmdex = section.substring(index+1, end_index);
229
 
230
                list.add(step);
231
 
232
                section = section.substring(end_index+2);
233
            }
234
            else if(section.startsWith("RETURN();")) {
235
 
236
                MicrocodeStep step = new MicrocodeStep();
237
                step.cmd   = null;
238
                step.type  = "RETURN";
239
                step.cmdex = null;
240
 
241
                list.add(step);
242
 
243
                section = section.substring(9);
244
            }
245
            else if(section.startsWith("ENDIF();")) {
246
                section = section.substring(8);
247
            }
248
            else throw new Exception("Unknown token: " + section.substring(0, (section.length()>100)? 100 : section.length()));
249
 
250
            section = section.trim();
251
        }
252
 
253
        //generate code for loops
254
        HashSet<String> loop_set = new HashSet<>();
255
 
256
        for(MicrocodeStep step : list) {
257
            if(step.type.equals("LOOP")) {
258
                if(loop_set.contains(step.cmd + step.cmdex) == false) {
259
                    if(build_loop.length() > 0) build_loop.append(" ||\n");
260
 
261
                    build_loop.append("(mc_cmd == " + step.cmd + " && mc_cmdex_last == " + step.cmdex + ")");
262
                    loop_set.add(step.cmd + step.cmdex);
263
                }
264
            }
265
        }
266
 
267
        //generate
268
        for(int i=1; i<list.size(); i++) {
269
            MicrocodeStep step1 = list.get(i-1);
270
            MicrocodeStep step2 = list.get(i);
271
 
272
            if(step1.type.equals("DIRECT")      && step2.type.equals("IF") == false) throw new Exception("DIRECT -> not IF");
273
            if(step1.type.equals("RETURN")      && step2.type.equals("IF") == false) throw new Exception("RETURN -> not IF");
274
            if(step1.type.equals("LAST_DIRECT") && step2.type.equals("IF") == false) throw new Exception("LAST_DIRECT -> not IF");
275
            if(step1.type.equals("LAST")        && step2.type.equals("IF") == false) throw new Exception("LAST -> not IF");
276
            if(step1.type.equals("JMP")         && step2.type.equals("IF") == false) throw new Exception("JMP -> not IF");
277
            if(step1.type.equals("LOOP")        && step2.type.equals("IF") == false) throw new Exception("LOOP -> not IF");
278
 
279
            if(step2.type.equals("IF")) continue;
280
 
281
            if(step1.type.equals("CALL")) continue;
282
 
283
            //prepare condition
284
            if(step1.type.equals("IF") && step1.cmd == null) {
285
                build.append("IF(" + step1.cmdex + ");\n");
286
            }
287
            else if(step1.type.equals("IF") && step1.cmd != null) {
288
                build.append("IF(mc_cmd == " + step1.cmd + " && " + step1.cmdex + ");\n");
289
            }
290
            else if(step1.type.equals("`")) {
291
                build.append("IF(mc_cmd == " + step1.cmd + " && mc_cmdex_last == " + step1.cmdex + ");\n");
292
            }
293
            else throw new Exception("Unexpected condition in step1");
294
 
295
            //prepare contents
296
            if(step2.type.equals("DIRECT")) {
297
                build.append("\tSET(mc_cmd_current,   " + step2.cmd   + ");\n");
298
                build.append("\tSET(mc_cmdex_current, " + step2.cmdex + ");\n");
299
                build.append("\tSET(mc_cmd_next,      " + step2.cmd   + "); //DIRECT\n");
300
            }
301
            else if(step2.type.equals("RETURN")) {
302
                build.append("\tSET(mc_cmd_current,   mc_saved_command);\n");
303
                build.append("\tSET(mc_cmdex_current, mc_saved_cmdex);\n");
304
                build.append("\tSET(mc_cmd_next,      mc_saved_command); //RETURN\n");
305
            }
306
            else if(step2.type.equals("LAST_DIRECT")) {
307
                build.append("\tSET(mc_cmd_current,   " + step2.cmd   + ");\n");
308
                build.append("\tSET(mc_cmdex_current, " + step2.cmdex + "); //LAST_DIRECT\n");
309
            }
310
            else if(step2.type.equals("LAST")) {
311
                build.append("\tSET(mc_cmd_current,   " + step2.cmd   + ");\n");
312
                build.append("\tSET(mc_cmdex_current, " + step2.cmdex + "); //LAST\n");
313
            }
314
            else if(step2.type.equals("JMP")) {
315
                build.append("\tSET(mc_cmd_current,   " + step2.cmd   + ");\n");
316
                build.append("\tSET(mc_cmdex_current, " + step2.cmdex + ");\n");
317
                build.append("\tSET(mc_cmd_next,      " + step2.cmd   + "); //JMP\n");
318
            }
319
            else if(step2.type.equals("CALL")) {
320
                build.append("\tSET(mc_cmd_current,   " + step2.cmd   + ");\n");
321
                build.append("\tSET(mc_cmdex_current, " + step2.cmdex + ");\n");
322
                build.append("\tSET(mc_cmd_next,      " + step2.cmd   + ");\n");
323
 
324
                MicrocodeStep step3 = list.get(i+1);
325
                if(step3.type.equals("DIRECT")) {
326
                    build.append("\tSAVE(mc_saved_command, " + step3.cmd   + ");\n");
327
                    build.append("\tSAVE(mc_saved_cmdex,   " + step3.cmdex + "); //CALL/DIRECT\n");
328
                }
329
                else if(step3.type.equals("LOOP")) {
330
                    build.append("\tSAVE(mc_saved_command, " + step3.cmd   + ");\n");
331
                    build.append("\tSAVE(mc_saved_cmdex,   " + step3.cmdex + "); //CALL/LOOP\n");
332
                }
333
                else if(step3.type.equals("`")) {
334
                    build.append("\tSAVE(mc_saved_command, " + step3.cmd   + ");\n");
335
                    build.append("\tSAVE(mc_saved_cmdex,   " + step3.cmdex + "); //CALL/`\n");
336
                }
337
                else throw new Exception("Unexpected step after CALL: " + step3.type);
338
            }
339
            else if(step2.type.equals("LOOP")) {
340
                build.append("\tSET(mc_cmd_current,   " + step2.cmd   + ");\n");
341
                build.append("\tSET(mc_cmdex_current, " + step2.cmdex + ");\n");
342
                build.append("\tSET(mc_cmd_next,      " + step2.cmd   + "); //LOOP\n");
343
            }
344
            else if(step2.type.equals("`")) {
345
                build.append("\tSET(mc_cmd_current,   " + step2.cmd   + ");\n");
346
                build.append("\tSET(mc_cmdex_current, " + step2.cmdex + ");\n");
347
                build.append("\tSET(mc_cmd_next,      " + step2.cmd   + "); //`\n");
348
            }
349
            else throw new Exception("Unexpected step2: " + step2.type);
350
 
351
            build.append("ENDIF();\n\n");
352
        }
353
    }
354
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.