This source file includes following definitions.
- main
- setarch
- emit_symbols
- list_symbols
- errout
- parse
- process
- define_symbol
- patch_label
- close_script
- new_script
- reserved
- CheckPhase
- CheckRegister
- expression
- evaluate
- number
- lookup
- f_arch
- f_proc
- f_pass
- f_list
- f_define
- store_inst
- f_move
- f_jump
- f_call
- f_return
- f_int
- f_intfly
- f_select
- f_reselect
- f_wait
- f_disconnect
- f_set
- f_clear
- f_load
- f_store
- f_nop
- loadstore
- transfer
- select_reselect
- set_clear
- block_move
- register_write
- memory_to_memory
- error_line
- makefn
- usage
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <time.h>
40
41 #ifndef AMIGA
42 #define strcmpi strcasecmp
43 #endif
44
45 #define MAXTOKENS 16
46 #define MAXINST 1024
47 #define MAXSYMBOLS 128
48
49 struct {
50 int type;
51 char *name;
52 } tokens[MAXTOKENS];
53 int ntokens;
54 int tokenix;
55
56 void f_proc (void);
57 void f_pass (void);
58 void f_list (void);
59 void f_define (void);
60 void f_move (void);
61 void f_jump (void);
62 void f_call (void);
63 void f_return (void);
64 void f_int (void);
65 void f_intfly (void);
66 void f_select (void);
67 void f_reselect (void);
68 void f_wait (void);
69 void f_disconnect (void);
70 void f_set (void);
71 void f_clear (void);
72 void f_load (void);
73 void f_store (void);
74 void f_nop (void);
75 void f_arch (void);
76
77 struct {
78 char *name;
79 void (*func)(void);
80 } directives[] = {
81 {"PROC", f_proc},
82 {"PASS", f_pass},
83 {"ENTRY", f_list},
84 {"ABSOLUTE", f_define},
85 {"EXTERN", f_list},
86 {"EXTERNAL", f_list},
87 {"RELATIVE", f_define},
88 {"MOVE", f_move},
89 {"JUMP", f_jump},
90 {"CALL", f_call},
91 {"RETURN", f_return},
92 {"INT", f_int},
93 {"INTFLY", f_intfly},
94 {"SELECT", f_select},
95 {"RESELECT", f_reselect},
96 {"WAIT", f_wait},
97 {"DISCONNECT", f_disconnect},
98 {"SET", f_set},
99 {"CLEAR", f_clear},
100 {"LOAD", f_load},
101 {"STORE", f_store},
102 {"NOP", f_nop},
103 {"ARCH", f_arch},
104 {NULL, NULL}};
105
106 u_int32_t script[MAXINST];
107 int dsps;
108 char *script_name = "SCRIPT";
109 u_int32_t inst0, inst1, inst2;
110 unsigned int ninsts;
111 unsigned int npatches;
112
113 struct patchlist {
114 struct patchlist *next;
115 unsigned offset;
116 } *patches;
117
118 #define S_LABEL 0x0000
119 #define S_ABSOLUTE 0x0001
120 #define S_RELATIVE 0x0002
121 #define S_EXTERNAL 0x0003
122 #define F_DEFINED 0x0001
123 #define F_ENTRY 0x0002
124 struct {
125 short type;
126 short flags;
127 u_int32_t value;
128 struct patchlist *patchlist;
129 char *name;
130 } symbols[MAXSYMBOLS];
131 int nsymbols;
132
133 char *stypes[] = {"Label", "Absolute", "Relative", "External"};
134
135 char *phases[] = {
136 "data_out", "data_in", "cmd", "status",
137 "res4", "res5", "msg_out", "msg_in"
138 };
139
140 struct ncrregs {
141 char *name;
142 int addr[5];
143 };
144 #define ARCH700 1
145 #define ARCH710 2
146 #define ARCH720 3
147 #define ARCH810 4
148 #define ARCH825 5
149
150 struct ncrregs regs[] = {
151 {"scntl0", {0x00, 0x00, 0x00, 0x00, 0x00}},
152 {"scntl1", {0x01, 0x01, 0x01, 0x01, 0x01}},
153 {"sdid", {0x02, 0x02, -1, -1, -1}},
154 {"sien", {0x03, 0x03, -1, -1, -1}},
155 {"scid", {0x04, 0x04, -1, -1, -1}},
156 {"scntl2", { -1, -1, 0x02, 0x02, 0x02}},
157 {"scntl3", { -1, -1, 0x03, 0x03, 0x03}},
158 {"scid", { -1, -1, 0x04, 0x04, 0x04}},
159 {"sxfer", {0x05, 0x05, 0x05, 0x05, 0x05}},
160 {"sodl", {0x06, 0x06, -1, -1, -1}},
161 {"socl", {0x07, 0x07, -1, -1, -1}},
162 {"sdid", { -1, -1, 0x06, 0x06, 0x06}},
163 {"gpreg", { -1, -1, 0x07, 0x07, 0x07}},
164 {"sfbr", {0x08, 0x08, 0x08, 0x08, 0x08}},
165 {"sidl", {0x09, 0x09, -1, -1, -1}},
166 {"sbdl", {0x0a, 0x0a, -1, -1, -1}},
167 {"socl", { -1, -1, 0x09, 0x09, 0x09}},
168 {"ssid", { -1, -1, 0x0a, 0x0a, 0x0a}},
169 {"sbcl", {0x0b, 0x0b, 0x0b, 0x0b, 0x0b}},
170 {"dstat", {0x0c, 0x0c, 0x0c, 0x0c, 0x0c}},
171 {"sstat0", {0x0d, 0x0d, 0x0d, 0x0d, 0x0d}},
172 {"sstat1", {0x0e, 0x0e, 0x0e, 0x0e, 0x0e}},
173 {"sstat2", {0x0f, 0x0f, 0x0f, 0x0f, 0x0f}},
174 {"dsa0", { -1, 0x10, 0x10, 0x10, 0x10}},
175 {"dsa1", { -1, 0x11, 0x11, 0x11, 0x11}},
176 {"dsa2", { -1, 0x12, 0x12, 0x12, 0x12}},
177 {"dsa3", { -1, 0x13, 0x13, 0x13, 0x13}},
178 {"ctest0", {0x14, 0x14, 0x18, 0x18, 0x18}},
179 {"ctest1", {0x15, 0x15, 0x19, 0x19, 0x19}},
180 {"ctest2", {0x16, 0x16, 0x1a, 0x1a, 0x1a}},
181 {"ctest3", {0x17, 0x17, 0x1b, 0x1b, 0x1b}},
182 {"ctest4", {0x18, 0x18, 0x21, 0x21, 0x21}},
183 {"ctest5", {0x19, 0x19, 0x22, 0x22, 0x22}},
184 {"ctest6", {0x1a, 0x1a, 0x23, 0x23, 0x23}},
185 {"ctest7", {0x1b, 0x1b, -1, -1, -1}},
186 {"temp0", {0x1c, 0x1c, 0x1c, 0x1c, 0x1c}},
187 {"temp1", {0x1d, 0x1d, 0x1d, 0x1d, 0x1d}},
188 {"temp2", {0x1e, 0x1e, 0x1e, 0x1e, 0x1e}},
189 {"temp3", {0x1f, 0x1f, 0x1f, 0x1f, 0x1f}},
190 {"dfifo", {0x20, 0x20, 0x20, 0x20, 0x20}},
191 {"istat", {0x21, 0x21, 0x14, 0x14, 0x14}},
192 {"ctest8", {0x22, 0x22, -1, -1, -1}},
193 {"lcrc", { -1, 0x23, -1, -1, -1}},
194 {"ctest9", {0x23, -1, -1, -1, -1}},
195 {"dbc0", {0x24, 0x24, 0x24, 0x24, 0x24}},
196 {"dbc1", {0x25, 0x25, 0x25, 0x25, 0x25}},
197 {"dbc2", {0x26, 0x26, 0x26, 0x26, 0x26}},
198 {"dcmd", {0x27, 0x27, 0x27, 0x27, 0x27}},
199 {"dnad0", {0x28, 0x28, 0x28, 0x28, 0x28}},
200 {"dnad1", {0x29, 0x29, 0x29, 0x29, 0x29}},
201 {"dnad2", {0x2a, 0x2a, 0x2a, 0x2a, 0x2a}},
202 {"dnad3", {0x2b, 0x2b, 0x2b, 0x2b, 0x2b}},
203 {"dsp0", {0x2c, 0x2c, 0x2c, 0x2c, 0x2c}},
204 {"dsp1", {0x2d, 0x2d, 0x2d, 0x2d, 0x2d}},
205 {"dsp2", {0x2e, 0x2e, 0x2e, 0x2e, 0x2e}},
206 {"dsp3", {0x2f, 0x2f, 0x2f, 0x2f, 0x2f}},
207 {"dsps0", {0x30, 0x30, 0x30, 0x30, 0x30}},
208 {"dsps1", {0x31, 0x31, 0x31, 0x31, 0x31}},
209 {"dsps2", {0x32, 0x32, 0x32, 0x32, 0x32}},
210 {"dsps3", {0x33, 0x33, 0x33, 0x33, 0x33}},
211 {"scratch0", { -1, 0x34, -1, -1, -1}},
212 {"scratch1", { -1, 0x35, -1, -1, -1}},
213 {"scratch2", { -1, 0x36, -1, -1, -1}},
214 {"scratch3", { -1, 0x37, -1, -1, -1}},
215 {"scratcha0", {0x10, -1, 0x34, 0x34, 0x34}},
216 {"scratcha1", {0x11, -1, 0x35, 0x35, 0x35}},
217 {"scratcha2", {0x12, -1, 0x36, 0x36, 0x36}},
218 {"scratcha3", {0x13, -1, 0x37, 0x37, 0x37}},
219 {"dmode", {0x34, 0x38, 0x38, 0x38, 0x38}},
220 {"dien", {0x39, 0x39, 0x39, 0x39, 0x39}},
221 {"dwt", {0x3a, 0x3a, 0x3a, -1, -1}},
222 {"sbr", { -1, -1, -1, 0x3a, 0x3a}},
223 {"dcntl", {0x3b, 0x3b, 0x3b, 0x3b, 0x3b}},
224 {"addr0", { -1, 0x3c, 0x3c, 0x3c, 0x3c}},
225 {"addr1", { -1, 0x3d, 0x3d, 0x3d, 0x3d}},
226 {"addr2", { -1, 0x3e, 0x3e, 0x3e, 0x3e}},
227 {"addr3", { -1, 0x3f, 0x3f, 0x3f, 0x3f}},
228 {"sien0", { -1, -1, 0x40, 0x40, 0x40}},
229 {"sien1", { -1, -1, 0x41, 0x41, 0x41}},
230 {"sist0", { -1, -1, 0x42, 0x42, 0x42}},
231 {"sist1", { -1, -1, 0x43, 0x43, 0x43}},
232 {"slpar", { -1, -1, 0x44, 0x44, 0x44}},
233 {"swide", { -1, -1, 0x45, -1, 0x45}},
234 {"macntl", { -1, -1, 0x46, 0x46, 0x46}},
235 {"gpcntl", { -1, -1, 0x47, 0x47, 0x47}},
236 {"stime0", { -1, -1, 0x48, 0x48, 0x48}},
237 {"stime1", { -1, -1, 0x49, 0x49, 0x49}},
238 {"respid0", { -1, -1, 0x4a, 0x4a, 0x4a}},
239 {"respid1", { -1, -1, 0x4b, -1, 0x4b}},
240 {"stest0", { -1, -1, 0x4c, 0x4c, 0x4c}},
241 {"stest1", { -1, -1, 0x4d, 0x4d, 0x4d}},
242 {"stest2", { -1, -1, 0x4e, 0x4e, 0x4e}},
243 {"stest3", { -1, -1, 0x4f, 0x4f, 0x4f}},
244 {"sidl0", { -1, -1, 0x50, 0x50, 0x50}},
245 {"sidl1", { -1, -1, 0x51, -1, 0x51}},
246 {"sodl0", { -1, -1, 0x54, 0x54, 0x54}},
247 {"sodl1", { -1, -1, 0x55, -1, 0x55}},
248 {"sbdl0", { -1, -1, 0x58, 0x58, 0x58}},
249 {"sbdl1", { -1, -1, 0x59, -1, 0x59}},
250 {"scratchb0", {0x3c, -1, 0x5c, 0x5c, 0x5c}},
251 {"scratchb1", {0x3d, -1, 0x5d, 0x5d, 0x5d}},
252 {"scratchb2", {0x3e, -1, 0x5e, 0x5e, 0x5e}},
253 {"scratchb3", {0x3f, -1, 0x5f, 0x5f, 0x5f}},
254 {"scratchc0", { -1, -1, -1, -1, 0x60}},
255 {"scratchc1", { -1, -1, -1, -1, 0x61}},
256 {"scratchc2", { -1, -1, -1, -1, 0x62}},
257 {"scratchc3", { -1, -1, -1, -1, 0x63}},
258 {"scratchd0", { -1, -1, -1, -1, 0x64}},
259 {"scratchd1", { -1, -1, -1, -1, 0x65}},
260 {"scratchd2", { -1, -1, -1, -1, 0x66}},
261 {"scratchd3", { -1, -1, -1, -1, 0x67}},
262 {"scratche0", { -1, -1, -1, -1, 0x68}},
263 {"scratche1", { -1, -1, -1, -1, 0x69}},
264 {"scratche2", { -1, -1, -1, -1, 0x6a}},
265 {"scratche3", { -1, -1, -1, -1, 0x6b}},
266 {"scratchf0", { -1, -1, -1, -1, 0x6c}},
267 {"scratchf1", { -1, -1, -1, -1, 0x6d}},
268 {"scratchf2", { -1, -1, -1, -1, 0x6e}},
269 {"scratchf3", { -1, -1, -1, -1, 0x6f}},
270 {"scratchg0", { -1, -1, -1, -1, 0x70}},
271 {"scratchg1", { -1, -1, -1, -1, 0x71}},
272 {"scratchg2", { -1, -1, -1, -1, 0x72}},
273 {"scratchg3", { -1, -1, -1, -1, 0x73}},
274 {"scratchh0", { -1, -1, -1, -1, 0x74}},
275 {"scratchh1", { -1, -1, -1, -1, 0x75}},
276 {"scratchh2", { -1, -1, -1, -1, 0x7e}},
277 {"scratchh3", { -1, -1, -1, -1, 0x77}},
278 {"scratchi0", { -1, -1, -1, -1, 0x78}},
279 {"scratchi1", { -1, -1, -1, -1, 0x79}},
280 {"scratchi2", { -1, -1, -1, -1, 0x7a}},
281 {"scratchi3", { -1, -1, -1, -1, 0x7b}},
282 {"scratchj0", { -1, -1, -1, -1, 0x7c}},
283 {"scratchj1", { -1, -1, -1, -1, 0x7d}},
284 {"scratchj2", { -1, -1, -1, -1, 0x7e}},
285 {"scratchj3", { -1, -1, -1, -1, 0x7f}},
286 };
287
288 int lineno;
289 int err_listed;
290 int arch;
291 int partial_flag;
292
293 char inbuf[128];
294
295 char *sourcefile;
296 char *outputfile;
297 char *listfile;
298 char *errorfile;
299
300 FILE *infp;
301 FILE *outfp;
302 FILE *listfp;
303 FILE *errfp;
304
305 void setarch(char *);
306 void parse (void);
307 void process (void);
308 void emit_symbols (void);
309 void list_symbols (void);
310 void errout (char *);
311 void define_symbol (char *, u_int32_t, short, short);
312 void patch_label (void);
313 void close_script (void);
314 void new_script (char *);
315 void store_inst (void);
316 int expression (int *);
317 int evaluate (int);
318 int number (char *);
319 int lookup (char *);
320 int reserved (char *, int);
321 int CheckPhase (int);
322 int CheckRegister (int);
323 void transfer (int, int);
324 void select_reselect (int);
325 void set_clear (u_int32_t);
326 void block_move (void);
327 void register_write (void);
328 void memory_to_memory (void);
329 void loadstore (int);
330 void error_line(void);
331 char *makefn(char *, char *);
332 void usage(void);
333
334 int
335 main (int argc, char *argv[])
336 {
337 int i;
338 struct patchlist *p;
339
340 if (argc < 2 || argv[1][0] == '-')
341 usage();
342 sourcefile = argv[1];
343 infp = fopen (sourcefile, "r");
344 if (infp == NULL) {
345 perror ("open source");
346 fprintf (stderr, "scc: error opening source file %s\n", argv[1]);
347 exit (1);
348 }
349
350
351
352
353
354
355
356
357
358
359
360 for (i = 2; i < argc; ++i) {
361 if (argv[i][0] != '-')
362 usage();
363 switch (argv[i][1]) {
364 case 'o':
365 case 'p':
366 partial_flag = argv[i][1] == 'p';
367 if (i + 1 >= argc || argv[i + 1][0] == '-')
368 outputfile = makefn (sourcefile, "out");
369 else {
370 outputfile = argv[i + 1];
371 ++i;
372 }
373 break;
374 case 'l':
375 if (i + 1 >= argc || argv[i + 1][0] == '-')
376 listfile = makefn (sourcefile, "lis");
377 else {
378 listfile = argv[i + 1];
379 ++i;
380 }
381 break;
382 case 'e':
383 if (i + 1 >= argc || argv[i + 1][0] == '-')
384 errorfile = makefn (sourcefile, "err");
385 else {
386 errorfile = argv[i + 1];
387 ++i;
388 }
389 break;
390 case 'a':
391 if (i + 1 == argc)
392 usage();
393 setarch(argv[i +1]);
394 if (arch == 0) {
395 fprintf(stderr,"%s: bad arch '%s'\n",
396 argv[0], argv[i +1]);
397 exit(1);
398 }
399 ++i;
400 break;
401 default:
402 fprintf (stderr, "scc: unrecognized option '%c'\n",
403 argv[i][1]);
404 usage();
405 }
406 }
407 if (outputfile)
408 outfp = fopen (outputfile, "w");
409 if (listfile)
410 listfp = fopen (listfile, "w");
411 if (errorfile)
412 errfp = fopen (errorfile, "w");
413 else
414 errfp = stderr;
415
416 if (outfp) {
417 time_t cur_time;
418
419 fprintf(outfp, "/*\t$OpenBSD: ncr53cxxx.c,v 1.7 2005/10/08 15:54:49 krw Exp $\t*/\n");
420 fprintf(outfp, "/*\n");
421 fprintf(outfp, " *\tDO NOT EDIT - this file is automatically generated.\n");
422 time(&cur_time);
423 fprintf(outfp, " *\tcreated from %s on %s", sourcefile, ctime(&cur_time));
424 fprintf(outfp, " */\n");
425 }
426
427 while (fgets (inbuf, sizeof (inbuf), infp)) {
428 ++lineno;
429 if (listfp)
430 fprintf (listfp, "%3d: %s", lineno, inbuf);
431 err_listed = 0;
432 parse ();
433 if (ntokens) {
434 #ifdef DUMP_TOKENS
435 int i;
436
437 fprintf (listfp, " %d tokens\n", ntokens);
438 for (i = 0; i < ntokens; ++i) {
439 fprintf (listfp, " %d: ", i);
440 if (tokens[i].type)
441 fprintf (listfp,"'%c'\n", tokens[i].type);
442 else
443 fprintf (listfp, "%s\n", tokens[i].name);
444 }
445 #endif
446 if (ntokens >= 2 && tokens[0].type == 0 &&
447 tokens[1].type == ':') {
448 define_symbol (tokens[0].name, dsps, S_LABEL, F_DEFINED);
449 tokenix += 2;
450 }
451 if (tokenix < ntokens)
452 process ();
453 }
454
455 }
456 close_script ();
457 emit_symbols ();
458 if (outfp && !partial_flag) {
459 fprintf (outfp, "\nu_int32_t INSTRUCTIONS = 0x%08x;\n", ninsts);
460 fprintf (outfp, "u_int32_t PATCHES = 0x%08x;\n", npatches);
461 fprintf (outfp, "u_int32_t LABELPATCHES[] = {\n");
462 p = patches;
463 while (p) {
464 fprintf (outfp, "\t0x%08x,\n", p->offset / 4);
465 p = p->next;
466 }
467 fprintf (outfp, "};\n\n");
468 }
469 list_symbols ();
470 exit(0);
471 }
472
473 void setarch(char *val)
474 {
475 switch (atoi(val)) {
476 case 700:
477 arch = ARCH700;
478 break;
479 case 710:
480 arch = ARCH710;
481 break;
482 case 720:
483 arch = ARCH720;
484 break;
485 case 810:
486 arch = ARCH810;
487 break;
488 case 825:
489 arch = ARCH825;
490 break;
491 default:
492 arch = 0;
493 }
494 }
495
496 void emit_symbols ()
497 {
498 int i;
499 struct patchlist *p;
500
501 if (nsymbols == 0 || outfp == NULL)
502 return;
503
504 for (i = 0; i < nsymbols; ++i) {
505 char *code;
506 if ((symbols[i].flags & F_DEFINED) == 0 &&
507 symbols[i].type != S_EXTERNAL) {
508 fprintf(stderr, "warning: symbol %s undefined\n",
509 symbols[i].name);
510 }
511 if (symbols[i].type == S_ABSOLUTE)
512 code = "A_";
513 else if (symbols[i].type == S_RELATIVE)
514 code = "R_";
515 else if (symbols[i].type == S_EXTERNAL)
516 code = "E_";
517 else if (symbols[i].flags & F_ENTRY)
518 code = "Ent_";
519 else
520 continue;
521 fprintf (outfp, "#define\t%s%s\t0x%08x\n", code, symbols[i].name,
522 symbols[i].value);
523 if (symbols[i].flags & F_ENTRY || symbols[i].patchlist == NULL)
524 continue;
525 fprintf (outfp, "u_int32_t %s%s_Used[] = {\n", code, symbols[i].name);
526 #if 1
527 p = symbols[i].patchlist;
528 while (p) {
529 fprintf (outfp, "\t0x%08x,\n", p->offset / 4);
530 p = p->next;
531 }
532 #endif
533 fprintf (outfp, "};\n\n");
534 }
535
536 }
537
538 void list_symbols ()
539 {
540 int i;
541
542 if (nsymbols == 0 || listfp == NULL)
543 return;
544 fprintf (listfp, "\n\nValue Type Symbol\n");
545 for (i = 0; i < nsymbols; ++i) {
546 fprintf (listfp, "%08x: %-8s %s\n", symbols[i].value,
547 stypes[symbols[i].type], symbols[i].name);
548 }
549 }
550
551 void errout (char *text)
552 {
553 error_line();
554 fprintf (errfp, "*** %s ***\n", text);
555 }
556
557 void parse ()
558 {
559 char *p = inbuf;
560 char c;
561 char string[64];
562 char *s;
563 size_t len;
564
565 ntokens = tokenix = 0;
566 while (1) {
567 while ((c = *p++) && c != '\n' && (c <= ' ' || c == '\t'))
568 ;
569 if (c == '\n' || c == 0 || c == ';')
570 break;
571 if (ntokens >= MAXTOKENS) {
572 errout ("Token table full");
573 break;
574 }
575 if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') ||
576 (c >= 'A' && c <= 'Z') || c == '$' || c == '_') {
577 s = string;
578 *s++ = c;
579 while (((c = *p) >= '0' && c <= '9') ||
580 (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
581 c == '_' || c == '$') {
582 *s++ = *p++;
583 }
584 *s = 0;
585 len = strlen (string) + 1;
586 tokens[ntokens].name = malloc (len);
587 strlcpy (tokens[ntokens].name, string, len);
588 tokens[ntokens].type = 0;
589 }
590 else {
591 tokens[ntokens].type = c;
592 }
593 ++ntokens;
594 }
595 return;
596 }
597
598 void process ()
599 {
600 int i;
601
602 if (tokens[tokenix].type) {
603 error_line();
604 fprintf (errfp, "Error: expected directive, found '%c'\n",
605 tokens[tokenix].type);
606 return;
607 }
608 for (i = 0; directives[i].name; ++i) {
609 if (strcmpi (directives[i].name, tokens[tokenix].name) == 0)
610 break;
611 }
612 if (directives[i].name == NULL) {
613 error_line();
614 fprintf (errfp, "Error: expected directive, found \"%s\"\n",
615 tokens[tokenix].name);
616 return;
617 }
618 if (directives[i].func == NULL) {
619 error_line();
620 fprintf (errfp, "No function for directive \"%s\"\n", tokens[tokenix].name);
621 } else {
622 #if 0
623 fprintf (listfp, "Processing directive \"%s\"\n", directives[i].name);
624 #endif
625 ++tokenix;
626 (*directives[i].func) ();
627 }
628 }
629
630 void define_symbol (char *name, u_int32_t value, short type, short flags)
631 {
632 int i;
633 struct patchlist *p;
634 size_t len;
635
636 for (i = 0; i < nsymbols; ++i) {
637 if (symbols[i].type == type && strcmp (symbols[i].name, name) == 0) {
638 if (symbols[i].flags & F_DEFINED) {
639 error_line();
640 fprintf (errfp, "*** Symbol \"%s\" multiply defined\n",
641 name);
642 } else {
643 symbols[i].flags |= flags;
644 symbols[i].value = value;
645 p = symbols[i].patchlist;
646 while (p) {
647 if (p->offset > dsps)
648 errout ("Whoops\007");
649 else
650 script[p->offset / 4] += dsps;
651 p = p->next;
652 }
653 }
654 return;
655 }
656 }
657 if (nsymbols >= MAXSYMBOLS) {
658 errout ("Symbol table full");
659 return;
660 }
661 symbols[nsymbols].type = type;
662 symbols[nsymbols].flags = flags;
663 symbols[nsymbols].value = value;
664 symbols[nsymbols].patchlist = NULL;
665 len = strlen (name) + 1;
666 symbols[nsymbols].name = malloc (len);
667 strlcpy (symbols[nsymbols].name, name, len);
668 ++nsymbols;
669 }
670
671 void patch_label (void)
672 {
673 struct patchlist *p, **h;
674
675 h = &patches;
676 while(*h)
677 h = &(*h)->next;
678 p = (struct patchlist *) malloc (sizeof (struct patchlist));
679 *h = p;
680 p->next = NULL;
681 p->offset = dsps + 4;
682 npatches++;
683 }
684
685 void close_script ()
686 {
687 int i;
688
689 if (dsps == 0)
690 return;
691 if (outfp) {
692 fprintf (outfp, "const u_int32_t %s[] = {\n", script_name);
693 for (i = 0; i < dsps / 4; i += 2) {
694 fprintf (outfp, "\t0x%08x, 0x%08x", script[i],
695 script[i + 1]);
696
697 if ((script[i] & 0xe0000000) == 0xc0000000)
698 fprintf (outfp, ", 0x%08x,", script[i + 2]);
699 else
700 if ((i + 2) <= dsps / 4) fprintf (outfp, ",\t\t");
701 fprintf (outfp, "\t/* %03x - %3d */\n", i * 4, i * 4);
702 if ((script[i] & 0xe0000000) == 0xc0000000)
703 ++i;
704 }
705 fprintf (outfp, "};\n\n");
706 }
707 dsps = 0;
708 }
709
710 void new_script (char *name)
711 {
712 size_t len = strlen (name) + 1;
713
714 close_script ();
715 script_name = malloc (len);
716 strlcpy (script_name, name, len);
717 }
718
719 int reserved (char *string, int t)
720 {
721 if (tokens[t].type == 0 && strcmpi (tokens[t].name, string) == 0)
722 return (1);
723 return (0);
724 }
725
726 int CheckPhase (int t)
727 {
728 int i;
729
730 for (i = 0; i < 8; ++i) {
731 if (reserved (phases[i], t)) {
732 inst0 |= i << 24;
733 return (1);
734 }
735 }
736 return (0);
737 }
738
739 int CheckRegister (int t)
740 {
741 int i;
742
743 if (arch <= 0) {
744 errout("'ARCH' statement missing");
745 return -1;
746 }
747 for (i = 0; i < (sizeof(regs) / sizeof(regs[0])); i++) {
748 if (regs[i].addr[arch - 1] >= 0 && reserved(regs[i].name, t))
749 return regs[i].addr[arch-1];
750 }
751 return (-1);
752 }
753
754 int expression (int *t)
755 {
756 int value;
757 int i = *t;
758
759 value = evaluate (i++);
760 while (i < ntokens) {
761 if (tokens[i].type == '+')
762 value += evaluate (i + 1);
763 else if (tokens[i].type == '-')
764 value -= evaluate (i + 1);
765 else
766 errout ("Unknown identifier");
767 i += 2;
768 }
769 *t = i;
770 return (value);
771 }
772
773 int evaluate (t)
774 {
775 int value;
776 char *name;
777
778 if (tokens[t].type) {
779 errout ("Expected an identifier");
780 return (0);
781 }
782 name = tokens[t].name;
783 if (*name >= '0' && *name <= '9')
784 value = number (name);
785 else
786 value = lookup (name);
787 return (value);
788 }
789
790 int number (char *s)
791 {
792 int value;
793 int n;
794 int radix;
795
796 radix = 10;
797 if (*s == '0') {
798 ++s;
799 radix = 8;
800 switch (*s) {
801 case 'x':
802 case 'X':
803 radix = 16;
804 break;
805 case 'b':
806 case 'B':
807 radix = 2;
808 }
809 if (radix != 8)
810 ++s;
811 }
812 value = 0;
813 while (*s) {
814 n = *s++;
815 if (n >= '0' && n <= '9')
816 n -= '0';
817 else if (n >= 'a' && n <= 'f')
818 n -= 'a' - 10;
819 else if (n >= 'A' && n <= 'F')
820 n -= 'A' - 10;
821 else {
822 error_line();
823 fprintf (errfp, "*** Expected digit\n");
824 n = 0;
825 }
826 if (n >= radix)
827 errout ("Expected digit");
828 else
829 value = value * radix + n;
830 }
831 return (value);
832 }
833
834 int lookup (char *name)
835 {
836 int i;
837 struct patchlist *p;
838 size_t len;
839
840 for (i = 0; i < nsymbols; ++i) {
841 if (strcmp (name, symbols[i].name) == 0) {
842 if ((symbols[i].flags & F_DEFINED) == 0) {
843 p = (struct patchlist *) &symbols[i].patchlist;
844 while (p->next)
845 p = p->next;
846 p->next = (struct patchlist *) malloc (sizeof (struct patchlist));
847 p = p->next;
848 p->next = NULL;
849 p->offset = dsps + 4;
850 }
851 return ((int) symbols[i].value);
852 }
853 }
854 if (nsymbols >= MAXSYMBOLS) {
855 errout ("Symbol table full");
856 return (0);
857 }
858 symbols[nsymbols].type = S_LABEL;
859 symbols[nsymbols].flags = 0;
860 symbols[nsymbols].value = 0;
861 p = (struct patchlist *) malloc (sizeof (struct patchlist));
862 symbols[nsymbols].patchlist = p;
863 p->next = NULL;
864 p->offset = dsps + 4;
865 len = strlen (name) + 1;
866 symbols[nsymbols].name = malloc (len);
867 strlcpy (symbols[nsymbols].name, name, len);
868 ++nsymbols;
869 return (0);
870 }
871
872 void f_arch (void)
873 {
874 int i, archsave;
875
876 i = tokenix;
877
878 archsave = arch;
879 setarch(tokens[i].name);
880 if( arch == 0) {
881 errout("Unrecognized ARCH");
882 arch = archsave;
883 }
884 }
885
886 void f_proc (void)
887 {
888 if (tokens[tokenix].type != 0 || tokens[tokenix + 1].type != ':')
889 errout ("Invalid PROC statement");
890 else
891 new_script (tokens[tokenix].name);
892 }
893
894 void f_pass (void)
895 {
896 errout ("PASS option not implemented");
897 }
898
899
900
901
902
903 void f_list (void)
904 {
905 int i;
906 short type;
907 short flags;
908
909 type = strcmpi (tokens[tokenix-1].name, "ENTRY") ? S_EXTERNAL : S_LABEL;
910 flags = type == S_LABEL ? F_ENTRY : 0;
911 for (i = tokenix; i < ntokens; ++i) {
912 if (tokens[i].type != 0) {
913 errout ("Expected an identifier");
914 return;
915 }
916 define_symbol (tokens[i].name, 0, type, flags);
917 if (i + 1 < ntokens) {
918 if (tokens[++i].type == ',')
919 continue;
920 errout ("Expected a separator");
921 return;
922 }
923 }
924 }
925
926
927
928
929
930 void f_define (void)
931 {
932 int i;
933 char *name;
934 u_int32_t value;
935 int type;
936
937 type = strcmpi (tokens[tokenix-1].name, "ABSOLUTE") ? S_RELATIVE : S_ABSOLUTE;
938 i = tokenix;
939 while (i < ntokens) {
940 if (tokens[i].type) {
941 errout ("Expected an identifier");
942 return;
943 }
944 if (tokens[i + 1].type != '=') {
945 errout ("Expected a separator");
946 return;
947 }
948 name = tokens[i].name;
949 i += 2;
950 value = expression (&i);
951 define_symbol (name, value, type, F_DEFINED);
952 }
953 }
954
955 void store_inst ()
956 {
957 int i = dsps / 4;
958 int l = 8;
959
960 if ((inst0 & 0xe0000000) == 0xc0000000)
961 l = 12;
962 if ((dsps + l) / 4 > MAXINST) {
963 errout ("Instruction table overflow");
964 return;
965 }
966 script[i++] = inst0;
967 script[i++] = inst1;
968 if (l == 12)
969 script[i++] = inst2;
970 if (listfp) {
971 fprintf (listfp, "\t%04x: %08x %08x", dsps, inst0, inst1);
972 if (l == 12)
973 fprintf (listfp, " %08x", inst2);
974 fprintf (listfp, "\n");
975 }
976 dsps += l;
977 inst0 = inst1 = inst2 = 0;
978 ++ninsts;
979 }
980
981 void f_move (void)
982 {
983 if (reserved ("memory", tokenix))
984 memory_to_memory ();
985 else if (reserved ("from", tokenix) || tokens[tokenix+1].type == ',')
986 block_move ();
987 else
988 register_write ();
989 store_inst ();
990 }
991
992 void f_jump (void)
993 {
994 transfer (0x80000000, 0);
995 }
996
997 void f_call (void)
998 {
999 transfer (0x88000000, 0);
1000 }
1001
1002 void f_return (void)
1003 {
1004 transfer (0x90000000, 1);
1005 }
1006
1007 void f_int (void)
1008 {
1009 transfer (0x98000000, 2);
1010 }
1011
1012 void f_intfly (void)
1013 {
1014 transfer (0x98100000, 2);
1015 }
1016
1017 void f_select (void)
1018 {
1019 int t = tokenix;
1020
1021 if (reserved ("atn", t)) {
1022 inst0 = 0x01000000;
1023 ++t;
1024 }
1025 select_reselect (t);
1026 }
1027
1028 void f_reselect (void)
1029 {
1030 select_reselect (tokenix);
1031 }
1032
1033 void f_wait (void)
1034 {
1035 int i = tokenix;
1036
1037 inst1 = 0;
1038 if (reserved ("disconnect", i)) {
1039 inst0 = 0x48000000;
1040 }
1041 else {
1042 if (reserved ("reselect", i))
1043 inst0 = 0x50000000;
1044 else if (reserved ("select", i))
1045 inst0 = 0x50000000;
1046 else
1047 errout ("Expected SELECT or RESELECT");
1048 ++i;
1049 if (reserved ("rel", i)) {
1050 #if 0
1051 if (arch < ARCH710) {
1052 errout ("Wrong arch for relative dsps");
1053 }
1054 #endif
1055 i += 2;
1056 inst1 = evaluate (i) - dsps - 8;
1057 inst0 |= 0x04000000;
1058 }
1059 else {
1060 inst1 = evaluate (i);
1061 patch_label();
1062 }
1063 }
1064 store_inst ();
1065 }
1066
1067 void f_disconnect (void)
1068 {
1069 inst0 = 0x48000000;
1070 store_inst ();
1071 }
1072
1073 void f_set (void)
1074 {
1075 set_clear (0x58000000);
1076 }
1077
1078 void f_clear (void)
1079 {
1080 set_clear (0x60000000);
1081 }
1082
1083 void f_load (void)
1084 {
1085 inst0 = 0xe1000000;
1086 if (arch < ARCH810) {
1087 errout ("Wrong arch for load/store");
1088 return;
1089 }
1090 loadstore(tokenix);
1091 }
1092
1093 void f_store (void)
1094 {
1095 int i;
1096 inst0 = 0xe0000000;
1097 if (arch < ARCH810) {
1098 errout ("Wrong arch for load/store");
1099 return;
1100 }
1101 i = tokenix;
1102 if (reserved("noflush", i)) {
1103 inst0 |= 0x2000000;
1104 i++;
1105 }
1106 loadstore(i);
1107 }
1108
1109 void f_nop (void)
1110 {
1111 inst0 = 0x80000000;
1112 inst1 = 0x00000000;
1113 store_inst ();
1114 }
1115
1116 void loadstore(int i)
1117 {
1118 int reg, size;
1119
1120 reg = CheckRegister(i);
1121 if (reg < 0)
1122 errout ("Expected register");
1123 else
1124 inst0 |= reg << 16;
1125 if (reg == 8)
1126 errout ("Register can't be SFBR");
1127 i++;
1128 if (tokens[i].type == ',')
1129 i++;
1130 else
1131 errout ("expected ','");
1132 size = evaluate(i);
1133 if (i < 1 || i > 4)
1134 errout("wrong size");
1135 if ((reg & 0x3) + size > 4)
1136 errout("size too big for register");
1137 inst0 |= size;
1138 i++;
1139 if (tokens[i].type == ',')
1140 i++;
1141 else
1142 errout ("expected ','");
1143 if (reserved("from", i) || reserved("dsarel", i)) {
1144 if (arch < ARCH710) {
1145 errout ("Wrong arch for table indirect");
1146 return;
1147 }
1148 i++;
1149 inst0 |= 0x10000000;
1150 }
1151 inst1 = evaluate(i);
1152 store_inst ();
1153 }
1154
1155 void transfer (int word0, int type)
1156 {
1157 int i;
1158
1159 i = tokenix;
1160 inst0 = word0;
1161 if (type == 0 && reserved ("rel", i)) {
1162 #if 0
1163 if (arch < ARCH710) {
1164 errout ("Wrong arch for relative dsps");
1165 }
1166 #endif
1167 inst1 = evaluate (i + 2) - dsps - 8;
1168 i += 4;
1169 inst0 |= 0x00800000;
1170 }
1171 else if (type != 1) {
1172 inst1 = evaluate (i);
1173 ++i;
1174 if (type == 0)
1175 patch_label();
1176 }
1177 if (i >= ntokens) {
1178 inst0 |= 0x00080000;
1179 store_inst ();
1180 return;
1181 }
1182 if (tokens[i].type != ',')
1183 errout ("Expected a separator, ',' assumed");
1184 else
1185 ++i;
1186 if (reserved("when", i))
1187 inst0 |= 0x00010000;
1188 else if (reserved ("if", i) == 0) {
1189 errout ("Expected a reserved word");
1190 store_inst ();
1191 return;
1192 }
1193 i++;
1194 if (reserved("false", i)) {
1195 store_inst ();
1196 return;
1197 }
1198 if (reserved ("not", i))
1199 ++i;
1200 else
1201 inst0 |= 0x00080000;
1202 if (reserved ("atn", i)) {
1203 inst0 |= 0x00020000;
1204 ++i;
1205 } else if (CheckPhase (i)) {
1206 inst0 |= 0x00020000;
1207 ++i;
1208 }
1209 if (i < ntokens && tokens[i].type != ',') {
1210 if (inst0 & 0x00020000) {
1211 if (inst0 & 0x00080000 && reserved ("and", i)) {
1212 ++i;
1213 }
1214 else if ((inst0 & 0x00080000) == 0 && reserved ("or", i)) {
1215 ++i;
1216 }
1217 else
1218 errout ("Expected a reserved word");
1219 }
1220 inst0 |= 0x00040000 + (evaluate (i++) & 0xff);
1221 }
1222 if (i < ntokens) {
1223 if (tokens[i].type == ',')
1224 ++i;
1225 else
1226 errout ("Expected a separator, ',' assumed");
1227 if (reserved ("and", i) && reserved ("mask", i + 1))
1228 inst0 |= ((evaluate (i + 2) & 0xff) << 8);
1229 else
1230 errout ("Expected , AND MASK");
1231 }
1232 store_inst ();
1233 }
1234
1235 void select_reselect (int t)
1236 {
1237 inst0 |= 0x40000000;
1238 if (reserved ("from", t)) {
1239 if (arch < ARCH710) {
1240 errout ("Wrong arch for table indirect");
1241 return;
1242 }
1243 ++t;
1244 inst0 |= 0x02000000 | evaluate (t++);
1245 }
1246 else
1247 inst0 |= (evaluate (t++) & 0xff) << 16;
1248 if (tokens[t++].type == ',') {
1249 if (reserved ("rel", t)) {
1250 #if 0
1251 if (arch < ARCH710) {
1252 errout ("Wrong arch for relative dsps");
1253 }
1254 #endif
1255 inst0 |= 0x04000000;
1256 inst1 = evaluate (t + 2) - dsps - 8;
1257 }
1258 else {
1259 inst1 = evaluate (t);
1260 patch_label();
1261 }
1262 }
1263 else
1264 errout ("Expected separator");
1265 store_inst ();
1266 }
1267
1268 void set_clear (u_int32_t code)
1269 {
1270 int i = tokenix;
1271 short need_and = 0;
1272
1273 inst0 = code;
1274 while (i < ntokens) {
1275 if (need_and) {
1276 if (reserved ("and", i))
1277 ++i;
1278 else
1279 errout ("Expected AND");
1280 }
1281 if (reserved ("atn", i)) {
1282 inst0 |= 0x0008;
1283 ++i;
1284 }
1285 else if (reserved ("ack", i)) {
1286 inst0 |= 0x0040;
1287 ++i;
1288 }
1289 else if (reserved ("target", i)) {
1290 inst0 |= 0x0200;
1291 ++i;
1292 }
1293 else if (reserved ("carry", i)) {
1294 inst0 |= 0x0400;
1295 ++i;
1296 }
1297 else
1298 errout ("Expected ATN, ACK, TARGET or CARRY");
1299 need_and = 1;
1300 }
1301 store_inst ();
1302 }
1303
1304 void block_move ()
1305 {
1306 if (reserved ("from", tokenix)) {
1307 if (arch < ARCH710) {
1308 errout ("Wrong arch for table indirect");
1309 return;
1310 }
1311 inst1 = evaluate (tokenix+1);
1312 inst0 |= 0x10000000 | inst1;
1313 tokenix += 2;
1314 }
1315 else {
1316 inst0 |= evaluate (tokenix++);
1317 tokenix++;
1318 if (reserved ("ptr", tokenix)) {
1319 ++tokenix;
1320 inst0 |= 0x20000000;
1321 }
1322 inst1 = evaluate (tokenix++);
1323 }
1324 if (tokens[tokenix].type != ',')
1325 errout ("Expected separator");
1326 if (reserved ("when", tokenix + 1)) {
1327 inst0 |= 0x08000000;
1328 CheckPhase (tokenix + 2);
1329 }
1330 else if (reserved ("with", tokenix + 1)) {
1331 CheckPhase (tokenix + 2);
1332 }
1333 else
1334 errout ("Expected WITH or WHEN");
1335 }
1336
1337 void register_write ()
1338 {
1339
1340
1341
1342
1343
1344 int op;
1345 int reg;
1346 int data;
1347
1348 if (reserved ("to", tokenix+1))
1349 op = 0;
1350 else if (reserved ("shl", tokenix+1))
1351 op = 1;
1352 else if (reserved ("shr", tokenix+1))
1353 op = 5;
1354 else if (tokens[tokenix+1].type == '|')
1355 op = 2;
1356 else if (reserved ("xor", tokenix+1))
1357 op = 3;
1358 else if (tokens[tokenix+1].type == '&')
1359 op = 4;
1360 else if (tokens[tokenix+1].type == '+')
1361 op = 6;
1362 else if (tokens[tokenix+1].type == '-')
1363 op = 8;
1364 else
1365 errout ("Unknown register operator");
1366 switch (op) {
1367 case 2:
1368 case 3:
1369 case 4:
1370 case 6:
1371 case 8:
1372 if (reserved ("to", tokenix+3) == 0)
1373 errout ("Register command expected TO");
1374 }
1375 reg = CheckRegister (tokenix);
1376 if (reg < 0) {
1377 data = evaluate (tokenix);
1378 if (op)
1379 errout ("Register operator not move");
1380 reg = CheckRegister (tokenix+2);
1381 if (reg < 0)
1382 errout ("Expected register");
1383 inst0 = 0x78000000 | (data << 8) | reg << 16;
1384 #if 0
1385 fprintf (listfp, "Move data to register: %02x %d\n", data, reg);
1386 #endif
1387 } else if (op) {
1388 switch (op) {
1389 case 2:
1390 case 3:
1391 case 4:
1392 case 6:
1393 case 8:
1394 inst0 = 0;
1395
1396 if (reserved("sfbr", tokenix+2)) {
1397 if (arch < ARCH825)
1398 errout("wrong arch for add with SFBR");
1399 if (op == 8)
1400 errout("can't substract SFBR");
1401 inst0 |= 0x00800000;
1402 data = 0;
1403 } else
1404 data = evaluate (tokenix+2);
1405 if (tokenix+5 < ntokens) {
1406 if (!reserved("with", tokenix+5) ||
1407 !reserved("carry", tokenix+6)) {
1408 errout("Expected 'WITH CARRY'");
1409 } else if (op != 6) {
1410 errout("'WITH CARRY' only valide "
1411 "with '+'");
1412 }
1413 op = 7;
1414 }
1415 if (op == 8) {
1416 data = -data;
1417 op = 6;
1418 }
1419 inst0 |= (data & 0xff) << 8;
1420 data = CheckRegister (tokenix+4);
1421 break;
1422 default:
1423 data = CheckRegister (tokenix+2);
1424 break;
1425 }
1426 if (data < 0)
1427 errout ("Expected register");
1428 if (reg != data && reg != 8 && data != 8)
1429 errout ("One register MUST be SBFR");
1430 if (reg == data) {
1431 #if 0
1432 fprintf (listfp, "Read/modify register: %02x %d %d\n", inst0 >> 8, op, reg);
1433 #endif
1434 inst0 |= 0x78000000 | (op << 24) | (reg << 16);
1435 }
1436 else {
1437 if (reg == 8) {
1438 #if 0
1439 fprintf (listfp, "Move SFBR to register: %02x %d %d\n", inst0 >> 8, op, data);
1440 #endif
1441 inst0 |= 0x68000000 | (op << 24) | (data << 16);
1442 }
1443 else {
1444 #if 0
1445 fprintf (listfp, "Move register to SFBR: %02x %d %d\n", inst0 >> 8, op, reg);
1446 #endif
1447 inst0 |= 0x70000000 | (op << 24) | (reg << 16);
1448 }
1449 }
1450 } else {
1451 data = CheckRegister (tokenix+2);
1452 if (data < 0)
1453 errout ("Expected register");
1454 if (reg == 8)
1455 inst0 = 0x6a000000 | (data << 16);
1456 else if (data == 8)
1457 inst0 = 0x72000000 | (reg << 16);
1458 else
1459 errout ("One register must be SFBR");
1460 }
1461 }
1462
1463 void memory_to_memory ()
1464 {
1465 inst0 = 0xc0000000 + evaluate (tokenix+1);
1466 inst1 = evaluate (tokenix+3);
1467
1468
1469
1470
1471 dsps += 4;
1472 inst2 = evaluate (tokenix+5);
1473 dsps -= 4;
1474 }
1475
1476 void error_line()
1477 {
1478 if (errfp != listfp && errfp && err_listed == 0) {
1479 fprintf (errfp, "%3d: %s", lineno, inbuf);
1480 err_listed = 1;
1481 }
1482 }
1483
1484 char * makefn (base, sub)
1485 char *base;
1486 char *sub;
1487 {
1488 char *fn;
1489 size_t len = strlen (base) + strlen (sub) + 2;
1490
1491 fn = malloc (len);
1492 strlcpy (fn, base, len);
1493 base = strrchr(fn, '.');
1494 if (base)
1495 *base = 0;
1496 strlcat (fn, ".", len);
1497 strlcat (fn, sub, len);
1498 return (fn);
1499 }
1500
1501 void usage()
1502 {
1503 fprintf (stderr, "usage: scc sourcfile [options]\n");
1504 exit(1);
1505 }