1 /* $NetBSD: ncr53cxxx.c,v 1.15 2005/12/11 12:22:36 christos Exp $ */
4 * Copyright (c) 1995,1999 Michael L. Hitch
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 /* ncr53cxxx.c - SCSI SCRIPTS Assembler */
30 #include <sys/cdefs.h>
31 __RCSID("$NetBSD: ncr53cxxx.c,v 1.15 2005/12/11 12:22:36 christos Exp $");
39 #define strcmpi strcasecmp
44 #define MAXSYMBOLS 128
55 void f_list (void); /* ENTRY, EXTERNAL label list */
56 void f_define (void); /* ABSOLUTE, RELATIVE label list */
64 void f_reselect (void);
66 void f_disconnect (void);
81 {"ABSOLUTE", f_define
},
84 {"RELATIVE", f_define
},
92 {"RESELECT", f_reselect
},
94 {"DISCONNECT", f_disconnect
},
103 u_int32_t script
[MAXINST
];
105 char *script_name
= "SCRIPT";
106 u_int32_t inst0
, inst1
, inst2
;
108 unsigned int npatches
;
111 struct patchlist
*next
;
115 #define S_LABEL 0x0000
116 #define S_ABSOLUTE 0x0001
117 #define S_RELATIVE 0x0002
118 #define S_EXTERNAL 0x0003
119 #define F_DEFINED 0x0001
120 #define F_ENTRY 0x0002
125 struct patchlist
*patchlist
;
127 } symbols
[MAXSYMBOLS
];
130 char *stypes
[] = {"Label", "Absolute", "Relative", "External"};
133 "data_out", "data_in", "cmd", "status",
134 "res4", "res5", "msg_out", "msg_in"
147 struct ncrregs regs
[] = {
148 {"scntl0", {0x00, 0x00, 0x00, 0x00, 0x00}},
149 {"scntl1", {0x01, 0x01, 0x01, 0x01, 0x01}},
150 {"sdid", {0x02, 0x02, -1, -1, -1}},
151 {"sien", {0x03, 0x03, -1, -1, -1}},
152 {"scid", {0x04, 0x04, -1, -1, -1}},
153 {"scntl2", { -1, -1, 0x02, 0x02, 0x02}},
154 {"scntl3", { -1, -1, 0x03, 0x03, 0x03}},
155 {"scid", { -1, -1, 0x04, 0x04, 0x04}},
156 {"sxfer", {0x05, 0x05, 0x05, 0x05, 0x05}},
157 {"sodl", {0x06, 0x06, -1, -1, -1}},
158 {"socl", {0x07, 0x07, -1, -1, -1}},
159 {"sdid", { -1, -1, 0x06, 0x06, 0x06}},
160 {"gpreg", { -1, -1, 0x07, 0x07, 0x07}},
161 {"sfbr", {0x08, 0x08, 0x08, 0x08, 0x08}},
162 {"sidl", {0x09, 0x09, -1, -1, -1}},
163 {"sbdl", {0x0a, 0x0a, -1, -1, -1}},
164 {"socl", { -1, -1, 0x09, 0x09, 0x09}},
165 {"ssid", { -1, -1, 0x0a, 0x0a, 0x0a}},
166 {"sbcl", {0x0b, 0x0b, 0x0b, 0x0b, 0x0b}},
167 {"dstat", {0x0c, 0x0c, 0x0c, 0x0c, 0x0c}},
168 {"sstat0", {0x0d, 0x0d, 0x0d, 0x0d, 0x0d}},
169 {"sstat1", {0x0e, 0x0e, 0x0e, 0x0e, 0x0e}},
170 {"sstat2", {0x0f, 0x0f, 0x0f, 0x0f, 0x0f}},
171 {"dsa0", { -1, 0x10, 0x10, 0x10, 0x10}},
172 {"dsa1", { -1, 0x11, 0x11, 0x11, 0x11}},
173 {"dsa2", { -1, 0x12, 0x12, 0x12, 0x12}},
174 {"dsa3", { -1, 0x13, 0x13, 0x13, 0x13}},
175 {"ctest0", {0x14, 0x14, 0x18, 0x18, 0x18}},
176 {"ctest1", {0x15, 0x15, 0x19, 0x19, 0x19}},
177 {"ctest2", {0x16, 0x16, 0x1a, 0x1a, 0x1a}},
178 {"ctest3", {0x17, 0x17, 0x1b, 0x1b, 0x1b}},
179 {"ctest4", {0x18, 0x18, 0x21, 0x21, 0x21}},
180 {"ctest5", {0x19, 0x19, 0x22, 0x22, 0x22}},
181 {"ctest6", {0x1a, 0x1a, 0x23, 0x23, 0x23}},
182 {"ctest7", {0x1b, 0x1b, -1, -1, -1}},
183 {"temp0", {0x1c, 0x1c, 0x1c, 0x1c, 0x1c}},
184 {"temp1", {0x1d, 0x1d, 0x1d, 0x1d, 0x1d}},
185 {"temp2", {0x1e, 0x1e, 0x1e, 0x1e, 0x1e}},
186 {"temp3", {0x1f, 0x1f, 0x1f, 0x1f, 0x1f}},
187 {"dfifo", {0x20, 0x20, 0x20, 0x20, 0x20}},
188 {"istat", {0x21, 0x21, 0x14, 0x14, 0x14}},
189 {"ctest8", {0x22, 0x22, -1, -1, -1}},
190 {"lcrc", { -1, 0x23, -1, -1, -1}},
191 {"ctest9", {0x23, -1, -1, -1, -1}},
192 {"dbc0", {0x24, 0x24, 0x24, 0x24, 0x24}},
193 {"dbc1", {0x25, 0x25, 0x25, 0x25, 0x25}},
194 {"dbc2", {0x26, 0x26, 0x26, 0x26, 0x26}},
195 {"dcmd", {0x27, 0x27, 0x27, 0x27, 0x27}},
196 {"dnad0", {0x28, 0x28, 0x28, 0x28, 0x28}},
197 {"dnad1", {0x29, 0x29, 0x29, 0x29, 0x29}},
198 {"dnad2", {0x2a, 0x2a, 0x2a, 0x2a, 0x2a}},
199 {"dnad3", {0x2b, 0x2b, 0x2b, 0x2b, 0x2b}},
200 {"dsp0", {0x2c, 0x2c, 0x2c, 0x2c, 0x2c}},
201 {"dsp1", {0x2d, 0x2d, 0x2d, 0x2d, 0x2d}},
202 {"dsp2", {0x2e, 0x2e, 0x2e, 0x2e, 0x2e}},
203 {"dsp3", {0x2f, 0x2f, 0x2f, 0x2f, 0x2f}},
204 {"dsps0", {0x30, 0x30, 0x30, 0x30, 0x30}},
205 {"dsps1", {0x31, 0x31, 0x31, 0x31, 0x31}},
206 {"dsps2", {0x32, 0x32, 0x32, 0x32, 0x32}},
207 {"dsps3", {0x33, 0x33, 0x33, 0x33, 0x33}},
208 {"scratch0", { -1, 0x34, -1, -1, -1}},
209 {"scratch1", { -1, 0x35, -1, -1, -1}},
210 {"scratch2", { -1, 0x36, -1, -1, -1}},
211 {"scratch3", { -1, 0x37, -1, -1, -1}},
212 {"scratcha0", {0x10, -1, 0x34, 0x34, 0x34}},
213 {"scratcha1", {0x11, -1, 0x35, 0x35, 0x35}},
214 {"scratcha2", {0x12, -1, 0x36, 0x36, 0x36}},
215 {"scratcha3", {0x13, -1, 0x37, 0x37, 0x37}},
216 {"dmode", {0x34, 0x38, 0x38, 0x38, 0x38}},
217 {"dien", {0x39, 0x39, 0x39, 0x39, 0x39}},
218 {"dwt", {0x3a, 0x3a, 0x3a, -1, -1}},
219 {"sbr", { -1, -1, -1, 0x3a, 0x3a}},
220 {"dcntl", {0x3b, 0x3b, 0x3b, 0x3b, 0x3b}},
221 {"addr0", { -1, 0x3c, 0x3c, 0x3c, 0x3c}},
222 {"addr1", { -1, 0x3d, 0x3d, 0x3d, 0x3d}},
223 {"addr2", { -1, 0x3e, 0x3e, 0x3e, 0x3e}},
224 {"addr3", { -1, 0x3f, 0x3f, 0x3f, 0x3f}},
225 {"sien0", { -1, -1, 0x40, 0x40, 0x40}},
226 {"sien1", { -1, -1, 0x41, 0x41, 0x41}},
227 {"sist0", { -1, -1, 0x42, 0x42, 0x42}},
228 {"sist1", { -1, -1, 0x43, 0x43, 0x43}},
229 {"slpar", { -1, -1, 0x44, 0x44, 0x44}},
230 {"swide", { -1, -1, 0x45, -1, 0x45}},
231 {"macntl", { -1, -1, 0x46, 0x46, 0x46}},
232 {"gpcntl", { -1, -1, 0x47, 0x47, 0x47}},
233 {"stime0", { -1, -1, 0x48, 0x48, 0x48}},
234 {"stime1", { -1, -1, 0x49, 0x49, 0x49}},
235 {"respid0", { -1, -1, 0x4a, 0x4a, 0x4a}},
236 {"respid1", { -1, -1, 0x4b, -1, 0x4b}},
237 {"stest0", { -1, -1, 0x4c, 0x4c, 0x4c}},
238 {"stest1", { -1, -1, 0x4d, 0x4d, 0x4d}},
239 {"stest2", { -1, -1, 0x4e, 0x4e, 0x4e}},
240 {"stest3", { -1, -1, 0x4f, 0x4f, 0x4f}},
241 {"sidl0", { -1, -1, 0x50, 0x50, 0x50}},
242 {"sidl1", { -1, -1, 0x51, -1, 0x51}},
243 {"sodl0", { -1, -1, 0x54, 0x54, 0x54}},
244 {"sodl1", { -1, -1, 0x55, -1, 0x55}},
245 {"sbdl0", { -1, -1, 0x58, 0x58, 0x58}},
246 {"sbdl1", { -1, -1, 0x59, -1, 0x59}},
247 {"scratchb0", {0x3c, -1, 0x5c, 0x5c, 0x5c}},
248 {"scratchb1", {0x3d, -1, 0x5d, 0x5d, 0x5d}},
249 {"scratchb2", {0x3e, -1, 0x5e, 0x5e, 0x5e}},
250 {"scratchb3", {0x3f, -1, 0x5f, 0x5f, 0x5f}},
251 {"scratchc0", { -1, -1, -1, -1, 0x60}},
252 {"scratchc1", { -1, -1, -1, -1, 0x61}},
253 {"scratchc2", { -1, -1, -1, -1, 0x62}},
254 {"scratchc3", { -1, -1, -1, -1, 0x63}},
255 {"scratchd0", { -1, -1, -1, -1, 0x64}},
256 {"scratchd1", { -1, -1, -1, -1, 0x65}},
257 {"scratchd2", { -1, -1, -1, -1, 0x66}},
258 {"scratchd3", { -1, -1, -1, -1, 0x67}},
259 {"scratche0", { -1, -1, -1, -1, 0x68}},
260 {"scratche1", { -1, -1, -1, -1, 0x69}},
261 {"scratche2", { -1, -1, -1, -1, 0x6a}},
262 {"scratche3", { -1, -1, -1, -1, 0x6b}},
263 {"scratchf0", { -1, -1, -1, -1, 0x6c}},
264 {"scratchf1", { -1, -1, -1, -1, 0x6d}},
265 {"scratchf2", { -1, -1, -1, -1, 0x6e}},
266 {"scratchf3", { -1, -1, -1, -1, 0x6f}},
267 {"scratchg0", { -1, -1, -1, -1, 0x70}},
268 {"scratchg1", { -1, -1, -1, -1, 0x71}},
269 {"scratchg2", { -1, -1, -1, -1, 0x72}},
270 {"scratchg3", { -1, -1, -1, -1, 0x73}},
271 {"scratchh0", { -1, -1, -1, -1, 0x74}},
272 {"scratchh1", { -1, -1, -1, -1, 0x75}},
273 {"scratchh2", { -1, -1, -1, -1, 0x7e}},
274 {"scratchh3", { -1, -1, -1, -1, 0x77}},
275 {"scratchi0", { -1, -1, -1, -1, 0x78}},
276 {"scratchi1", { -1, -1, -1, -1, 0x79}},
277 {"scratchi2", { -1, -1, -1, -1, 0x7a}},
278 {"scratchi3", { -1, -1, -1, -1, 0x7b}},
279 {"scratchj0", { -1, -1, -1, -1, 0x7c}},
280 {"scratchj1", { -1, -1, -1, -1, 0x7d}},
281 {"scratchj2", { -1, -1, -1, -1, 0x7e}},
282 {"scratchj3", { -1, -1, -1, -1, 0x7f}},
302 void setarch(char *);
305 void emit_symbols (void);
306 void list_symbols (void);
307 void errout (char *);
308 void define_symbol (char *, u_int32_t
, short, short);
309 void patch_label (void);
310 void close_script (void);
311 void new_script (char *);
312 void store_inst (void);
313 int expression (int *);
317 int reserved (char *, int);
318 int CheckPhase (int);
319 int CheckRegister (int);
320 void transfer (int, int);
321 void select_reselect (int);
322 void set_clear (u_int32_t
);
323 void block_move (void);
324 void register_write (void);
325 void memory_to_memory (void);
326 void loadstore (int);
327 void error_line(void);
328 char *makefn(char *, char *);
332 main (int argc
, char *argv
[])
337 if (argc
< 2 || argv
[1][0] == '-')
339 sourcefile
= argv
[1];
340 infp
= fopen (sourcefile
, "r");
342 perror ("open source");
343 fprintf (stderr
, "scc: error opening source file %s\n", argv
[1]);
357 for (i
= 2; i
< argc
; ++i
) {
358 if (argv
[i
][0] != '-')
360 switch (argv
[i
][1]) {
363 partial_flag
= argv
[i
][1] == 'p';
364 if (i
+ 1 >= argc
|| argv
[i
+ 1][0] == '-')
365 outputfile
= makefn (sourcefile
, "out");
367 outputfile
= argv
[i
+ 1];
372 if (i
+ 1 >= argc
|| argv
[i
+ 1][0] == '-')
373 listfile
= makefn (sourcefile
, "lis");
375 listfile
= argv
[i
+ 1];
380 if (i
+ 1 >= argc
|| argv
[i
+ 1][0] == '-')
381 errorfile
= makefn (sourcefile
, "err");
383 errorfile
= argv
[i
+ 1];
392 fprintf(stderr
,"%s: bad arch '%s'\n",
393 argv
[0], argv
[i
+1]);
399 fprintf (stderr
, "scc: unrecognized option '%c'\n",
405 outfp
= fopen (outputfile
, "w");
407 listfp
= fopen (listfile
, "w");
409 errfp
= fopen (errorfile
, "w");
416 fprintf(outfp
, "/*\t$NetBSD: ncr53cxxx.c,v 1.15 2005/12/11 12:22:36 christos Exp $\t*/\n");
417 fprintf(outfp
, "/*\n");
418 fprintf(outfp
, " *\tDO NOT EDIT - this file is automatically generated.\n");
420 fprintf(outfp
, " *\tcreated from %s on %s", sourcefile
, ctime(&cur_time
));
421 fprintf(outfp
, " */\n");
424 while (fgets (inbuf
, sizeof (inbuf
), infp
)) {
427 fprintf (listfp
, "%3d: %s", lineno
, inbuf
);
434 fprintf (listfp
, " %d tokens\n", ntokens
);
435 for (i
= 0; i
< ntokens
; ++i
) {
436 fprintf (listfp
, " %d: ", i
);
438 fprintf (listfp
,"'%c'\n", tokens
[i
].type
);
440 fprintf (listfp
, "%s\n", tokens
[i
].name
);
443 if (ntokens
>= 2 && tokens
[0].type
== 0 &&
444 tokens
[1].type
== ':') {
445 define_symbol (tokens
[0].name
, dsps
, S_LABEL
, F_DEFINED
);
448 if (tokenix
< ntokens
)
455 if (outfp
&& !partial_flag
) {
456 fprintf (outfp
, "\nu_int32_t INSTRUCTIONS = 0x%08x;\n", ninsts
);
457 fprintf (outfp
, "u_int32_t PATCHES = 0x%08x;\n", npatches
);
458 fprintf (outfp
, "u_int32_t LABELPATCHES[] = {\n");
461 fprintf (outfp
, "\t0x%08x,\n", p
->offset
/ 4);
464 fprintf (outfp
, "};\n\n");
470 void setarch(char *val
)
498 if (nsymbols
== 0 || outfp
== NULL
)
501 for (i
= 0; i
< nsymbols
; ++i
) {
503 if ((symbols
[i
].flags
& F_DEFINED
) == 0 &&
504 symbols
[i
].type
!= S_EXTERNAL
) {
505 fprintf(stderr
, "warning: symbol %s undefined\n",
508 if (symbols
[i
].type
== S_ABSOLUTE
)
510 else if (symbols
[i
].type
== S_RELATIVE
)
512 else if (symbols
[i
].type
== S_EXTERNAL
)
514 else if (symbols
[i
].flags
& F_ENTRY
)
518 fprintf (outfp
, "#define\t%s%s\t0x%08x\n", code
, symbols
[i
].name
,
520 if (symbols
[i
].flags
& F_ENTRY
|| symbols
[i
].patchlist
== NULL
)
522 fprintf (outfp
, "u_int32_t %s%s_Used[] = {\n", code
, symbols
[i
].name
);
524 p
= symbols
[i
].patchlist
;
526 fprintf (outfp
, "\t0x%08x,\n", p
->offset
/ 4);
530 fprintf (outfp
, "};\n\n");
539 if (nsymbols
== 0 || listfp
== NULL
)
541 fprintf (listfp
, "\n\nValue Type Symbol\n");
542 for (i
= 0; i
< nsymbols
; ++i
) {
543 fprintf (listfp
, "%08x: %-8s %s\n", symbols
[i
].value
,
544 stypes
[symbols
[i
].type
], symbols
[i
].name
);
548 void errout (char *text
)
551 fprintf (errfp
, "*** %s ***\n", text
);
561 ntokens
= tokenix
= 0;
563 while ((c
= *p
++) && c
!= '\n' && (c
<= ' ' || c
== '\t'))
565 if (c
== '\n' || c
== 0 || c
== ';')
567 if (ntokens
>= MAXTOKENS
) {
568 errout ("Token table full");
571 if ((c
>= '0' && c
<= '9') || (c
>= 'a' && c
<= 'z') ||
572 (c
>= 'A' && c
<= 'Z') || c
== '$' || c
== '_') {
575 while (((c
= *p
) >= '0' && c
<= '9') ||
576 (c
>= 'a' && c
<= 'z') || (c
>= 'A' && c
<= 'Z') ||
577 c
== '_' || c
== '$') {
581 tokens
[ntokens
].name
= malloc (strlen (string
) + 1);
582 strcpy (tokens
[ntokens
].name
, string
);
583 tokens
[ntokens
].type
= 0;
586 tokens
[ntokens
].type
= c
;
597 if (tokens
[tokenix
].type
) {
599 fprintf (errfp
, "Error: expected directive, found '%c'\n",
600 tokens
[tokenix
].type
);
603 for (i
= 0; directives
[i
].name
; ++i
) {
604 if (strcmpi (directives
[i
].name
, tokens
[tokenix
].name
) == 0)
607 if (directives
[i
].name
== NULL
) {
609 fprintf (errfp
, "Error: expected directive, found \"%s\"\n",
610 tokens
[tokenix
].name
);
613 if (directives
[i
].func
== NULL
) {
615 fprintf (errfp
, "No function for directive \"%s\"\n", tokens
[tokenix
].name
);
618 fprintf (listfp
, "Processing directive \"%s\"\n", directives
[i
].name
);
621 (*directives
[i
].func
) ();
625 void define_symbol (char *name
, u_int32_t value
, short type
, short flags
)
630 for (i
= 0; i
< nsymbols
; ++i
) {
631 if (symbols
[i
].type
== type
&& strcmp (symbols
[i
].name
, name
) == 0) {
632 if (symbols
[i
].flags
& F_DEFINED
) {
634 fprintf (errfp
, "*** Symbol \"%s\" multiply defined\n",
637 symbols
[i
].flags
|= flags
;
638 symbols
[i
].value
= value
;
639 p
= symbols
[i
].patchlist
;
641 if (p
->offset
> dsps
)
642 errout ("Whoops\007");
644 script
[p
->offset
/ 4] += dsps
;
651 if (nsymbols
>= MAXSYMBOLS
) {
652 errout ("Symbol table full");
655 symbols
[nsymbols
].type
= type
;
656 symbols
[nsymbols
].flags
= flags
;
657 symbols
[nsymbols
].value
= value
;
658 symbols
[nsymbols
].patchlist
= NULL
;
659 symbols
[nsymbols
].name
= malloc (strlen (name
) + 1);
660 strcpy (symbols
[nsymbols
].name
, name
);
664 void patch_label (void)
666 struct patchlist
*p
, **h
;
671 p
= (struct patchlist
*) malloc (sizeof (struct patchlist
));
674 p
->offset
= dsps
+ 4;
685 fprintf (outfp
, "const u_int32_t %s[] = {\n", script_name
);
686 for (i
= 0; i
< dsps
/ 4; i
+= 2) {
687 fprintf (outfp
, "\t0x%08x, 0x%08x", script
[i
],
689 /* check for memory move instruction */
690 if ((script
[i
] & 0xe0000000) == 0xc0000000)
691 fprintf (outfp
, ", 0x%08x,", script
[i
+ 2]);
693 if ((i
+ 2) <= dsps
/ 4) fprintf (outfp
, ",\t\t");
694 fprintf (outfp
, "\t/* %03x - %3d */\n", i
* 4, i
* 4);
695 if ((script
[i
] & 0xe0000000) == 0xc0000000)
698 fprintf (outfp
, "};\n\n");
703 void new_script (char *name
)
706 script_name
= malloc (strlen (name
) + 1);
707 strcpy (script_name
, name
);
710 int reserved (char *string
, int t
)
712 if (tokens
[t
].type
== 0 && strcmpi (tokens
[t
].name
, string
) == 0)
717 int CheckPhase (int t
)
721 for (i
= 0; i
< 8; ++i
) {
722 if (reserved (phases
[i
], t
)) {
730 int CheckRegister (int t
)
735 errout("'ARCH' statement missing");
738 for (i
= 0; i
< (sizeof(regs
) / sizeof(regs
[0])); i
++) {
739 if (regs
[i
].addr
[arch
- 1] >= 0 && reserved(regs
[i
].name
, t
))
740 return regs
[i
].addr
[arch
-1];
745 int expression (int *t
)
750 value
= evaluate (i
++);
751 while (i
< ntokens
) {
752 if (tokens
[i
].type
== '+')
753 value
+= evaluate (i
+ 1);
754 else if (tokens
[i
].type
== '-')
755 value
-= evaluate (i
+ 1);
757 errout ("Unknown identifier");
769 if (tokens
[t
].type
) {
770 errout ("Expected an identifier");
773 name
= tokens
[t
].name
;
774 if (*name
>= '0' && *name
<= '9')
775 value
= number (name
);
777 value
= lookup (name
);
806 if (n
>= '0' && n
<= '9')
808 else if (n
>= 'a' && n
<= 'f')
810 else if (n
>= 'A' && n
<= 'F')
814 fprintf (errfp
, "*** Expected digit\n");
818 errout ("Expected digit");
820 value
= value
* radix
+ n
;
825 int lookup (char *name
)
830 for (i
= 0; i
< nsymbols
; ++i
) {
831 if (strcmp (name
, symbols
[i
].name
) == 0) {
832 if ((symbols
[i
].flags
& F_DEFINED
) == 0) {
833 p
= (struct patchlist
*) &symbols
[i
].patchlist
;
836 p
->next
= (struct patchlist
*) malloc (sizeof (struct patchlist
));
839 p
->offset
= dsps
+ 4;
841 return ((int) symbols
[i
].value
);
844 if (nsymbols
>= MAXSYMBOLS
) {
845 errout ("Symbol table full");
848 symbols
[nsymbols
].type
= S_LABEL
; /* assume forward reference */
849 symbols
[nsymbols
].flags
= 0;
850 symbols
[nsymbols
].value
= 0;
851 p
= (struct patchlist
*) malloc (sizeof (struct patchlist
));
852 symbols
[nsymbols
].patchlist
= p
;
854 p
->offset
= dsps
+ 4;
855 symbols
[nsymbols
].name
= malloc (strlen (name
) + 1);
856 strcpy (symbols
[nsymbols
].name
, name
);
868 setarch(tokens
[i
].name
);
870 errout("Unrecognized ARCH");
877 if (tokens
[tokenix
].type
!= 0 || tokens
[tokenix
+ 1].type
!= ':')
878 errout ("Invalid PROC statement");
880 new_script (tokens
[tokenix
].name
);
885 errout ("PASS option not implemented");
889 * f_list: process list of symbols for the ENTRY and EXTERNAL directive
898 type
= strcmpi (tokens
[tokenix
-1].name
, "ENTRY") ? S_EXTERNAL
: S_LABEL
;
899 flags
= type
== S_LABEL
? F_ENTRY
: 0;
900 for (i
= tokenix
; i
< ntokens
; ++i
) {
901 if (tokens
[i
].type
!= 0) {
902 errout ("Expected an identifier");
905 define_symbol (tokens
[i
].name
, 0, type
, flags
);
906 if (i
+ 1 < ntokens
) {
907 if (tokens
[++i
].type
== ',')
909 errout ("Expected a separator");
916 * f_define: process list of definitions for ABSOLUTE and RELATIVE directive
926 type
= strcmpi (tokens
[tokenix
-1].name
, "ABSOLUTE") ? S_RELATIVE
: S_ABSOLUTE
;
928 while (i
< ntokens
) {
929 if (tokens
[i
].type
) {
930 errout ("Expected an identifier");
933 if (tokens
[i
+ 1].type
!= '=') {
934 errout ("Expected a separator");
937 name
= tokens
[i
].name
;
939 value
= expression (&i
);
940 define_symbol (name
, value
, type
, F_DEFINED
);
949 if ((inst0
& 0xe0000000) == 0xc0000000)
950 l
= 12; /* Memory to memory move is 12 bytes */
951 if ((dsps
+ l
) / 4 > MAXINST
) {
952 errout ("Instruction table overflow");
960 fprintf (listfp
, "\t%04x: %08x %08x", dsps
, inst0
, inst1
);
962 fprintf (listfp
, " %08x", inst2
);
963 fprintf (listfp
, "\n");
966 inst0
= inst1
= inst2
= 0;
972 if (reserved ("memory", tokenix
))
974 else if (reserved ("from", tokenix
) || tokens
[tokenix
+1].type
== ',')
983 transfer (0x80000000, 0);
988 transfer (0x88000000, 0);
993 transfer (0x90000000, 1);
998 transfer (0x98000000, 2);
1001 void f_intfly (void)
1003 transfer (0x98100000, 2);
1006 void f_select (void)
1010 if (reserved ("atn", t
)) {
1014 select_reselect (t
);
1017 void f_reselect (void)
1019 select_reselect (tokenix
);
1027 if (reserved ("disconnect", i
)) {
1031 if (reserved ("reselect", i
))
1033 else if (reserved ("select", i
))
1036 errout ("Expected SELECT or RESELECT");
1038 if (reserved ("rel", i
)) {
1039 #if 0 /* driver will fix relative dsps to absolute */
1040 if (arch
< ARCH710
) {
1041 errout ("Wrong arch for relative dsps");
1045 inst1
= evaluate (i
) - dsps
- 8;
1046 inst0
|= 0x04000000;
1049 inst1
= evaluate (i
);
1056 void f_disconnect (void)
1064 set_clear (0x58000000);
1069 set_clear (0x60000000);
1075 if (arch
< ARCH810
) {
1076 errout ("Wrong arch for load/store");
1086 if (arch
< ARCH810
) {
1087 errout ("Wrong arch for load/store");
1091 if (reserved("noflush", i
)) {
1105 void loadstore(int i
)
1109 reg
= CheckRegister(i
);
1111 errout ("Expected register");
1115 errout ("Register can't be SFBR");
1117 if (tokens
[i
].type
== ',')
1120 errout ("expected ','");
1123 errout("wrong size");
1124 if ((reg
& 0x3) + size
> 4)
1125 errout("size too big for register");
1128 if (tokens
[i
].type
== ',')
1131 errout ("expected ','");
1132 if (reserved("from", i
) || reserved("dsarel", i
)) {
1133 if (arch
< ARCH710
) {
1134 errout ("Wrong arch for table indirect");
1138 inst0
|= 0x10000000;
1140 inst1
= evaluate(i
);
1144 void transfer (int word0
, int type
)
1150 if (type
== 0 && reserved ("rel", i
)) {
1151 #if 0 /* driver will fix relative dsps to absolute */
1152 if (arch
< ARCH710
) {
1153 errout ("Wrong arch for relative dsps");
1156 inst1
= evaluate (i
+ 2) - dsps
- 8;
1158 inst0
|= 0x00800000;
1160 else if (type
!= 1) {
1161 inst1
= evaluate (i
);
1167 inst0
|= 0x00080000;
1171 if (tokens
[i
].type
!= ',')
1172 errout ("Expected a separator, ',' assumed");
1175 if (reserved("when", i
))
1176 inst0
|= 0x00010000;
1177 else if (reserved ("if", i
) == 0) {
1178 errout ("Expected a reserved word");
1183 if (reserved("false", i
)) {
1187 if (reserved ("not", i
))
1190 inst0
|= 0x00080000;
1191 if (reserved ("atn", i
)) {
1192 inst0
|= 0x00020000;
1194 } else if (CheckPhase (i
)) {
1195 inst0
|= 0x00020000;
1198 if (i
< ntokens
&& tokens
[i
].type
!= ',') {
1199 if (inst0
& 0x00020000) {
1200 if (inst0
& 0x00080000 && reserved ("and", i
)) {
1203 else if ((inst0
& 0x00080000) == 0 && reserved ("or", i
)) {
1207 errout ("Expected a reserved word");
1209 inst0
|= 0x00040000 + (evaluate (i
++) & 0xff);
1212 if (tokens
[i
].type
== ',')
1215 errout ("Expected a separator, ',' assumed");
1216 if (reserved ("and", i
) && reserved ("mask", i
+ 1))
1217 inst0
|= ((evaluate (i
+ 2) & 0xff) << 8);
1219 errout ("Expected , AND MASK");
1224 void select_reselect (int t
)
1226 inst0
|= 0x40000000; /* ATN may be set from SELECT */
1227 if (reserved ("from", t
)) {
1228 if (arch
< ARCH710
) {
1229 errout ("Wrong arch for table indirect");
1233 inst0
|= 0x02000000 | evaluate (t
++);
1236 inst0
|= (evaluate (t
++) & 0xff) << 16;
1237 if (tokens
[t
++].type
== ',') {
1238 if (reserved ("rel", t
)) {
1239 #if 0 /* driver will fix relative dsps to absolute */
1240 if (arch
< ARCH710
) {
1241 errout ("Wrong arch for relative dsps");
1244 inst0
|= 0x04000000;
1245 inst1
= evaluate (t
+ 2) - dsps
- 8;
1248 inst1
= evaluate (t
);
1253 errout ("Expected separator");
1257 void set_clear (u_int32_t code
)
1263 while (i
< ntokens
) {
1265 if (reserved ("and", i
))
1268 errout ("Expected AND");
1270 if (reserved ("atn", i
)) {
1274 else if (reserved ("ack", i
)) {
1278 else if (reserved ("target", i
)) {
1282 else if (reserved ("carry", i
)) {
1287 errout ("Expected ATN, ACK, TARGET or CARRY");
1295 if (reserved ("from", tokenix
)) {
1296 if (arch
< ARCH710
) {
1297 errout ("Wrong arch for table indirect");
1300 inst1
= evaluate (tokenix
+1);
1301 inst0
|= 0x10000000 | inst1
; /*** ??? to match Zeus script */
1305 inst0
|= evaluate (tokenix
++); /* count */
1306 tokenix
++; /* skip ',' */
1307 if (reserved ("ptr", tokenix
)) {
1309 inst0
|= 0x20000000;
1311 inst1
= evaluate (tokenix
++); /* address */
1313 if (tokens
[tokenix
].type
!= ',')
1314 errout ("Expected separator");
1315 if (reserved ("when", tokenix
+ 1)) {
1316 inst0
|= 0x08000000;
1317 CheckPhase (tokenix
+ 2);
1319 else if (reserved ("with", tokenix
+ 1)) {
1320 CheckPhase (tokenix
+ 2);
1323 errout ("Expected WITH or WHEN");
1326 void register_write ()
1329 * MOVE reg/data8 TO reg register write
1330 * MOVE reg <op> data8 TO reg register write
1331 * MOVE reg + data8 TO reg WITH CARRY register write
1337 if (reserved ("to", tokenix
+1))
1339 else if (reserved ("shl", tokenix
+1))
1341 else if (reserved ("shr", tokenix
+1))
1343 else if (tokens
[tokenix
+1].type
== '|')
1345 else if (reserved ("xor", tokenix
+1))
1347 else if (tokens
[tokenix
+1].type
== '&')
1349 else if (tokens
[tokenix
+1].type
== '+')
1351 else if (tokens
[tokenix
+1].type
== '-')
1354 errout ("Unknown register operator");
1361 if (reserved ("to", tokenix
+3) == 0)
1362 errout ("Register command expected TO");
1364 reg
= CheckRegister (tokenix
);
1365 if (reg
< 0) { /* Not register, must be data */
1366 data
= evaluate (tokenix
);
1368 errout ("Register operator not move");
1369 reg
= CheckRegister (tokenix
+2);
1371 errout ("Expected register");
1372 inst0
= 0x78000000 | (data
<< 8) | reg
<< 16;
1374 fprintf (listfp
, "Move data to register: %02x %d\n", data
, reg
);
1384 /* A register read/write operator */
1385 if (reserved("sfbr", tokenix
+2)) {
1387 errout("wrong arch for add with SFBR");
1389 errout("can't substract SFBR");
1390 inst0
|= 0x00800000;
1393 data
= evaluate (tokenix
+2);
1394 if (tokenix
+5 < ntokens
) {
1395 if (!reserved("with", tokenix
+5) ||
1396 !reserved("carry", tokenix
+6)) {
1397 errout("Expected 'WITH CARRY'");
1398 } else if (op
!= 6) {
1399 errout("'WITH CARRY' only valide "
1408 inst0
|= (data
& 0xff) << 8;
1409 data
= CheckRegister (tokenix
+4);
1412 data
= CheckRegister (tokenix
+2);
1416 errout ("Expected register");
1417 if (reg
!= data
&& reg
!= 8 && data
!= 8)
1418 errout ("One register MUST be SBFR");
1419 if (reg
== data
) { /* A register read/modify/write */
1421 fprintf (listfp
, "Read/modify register: %02x %d %d\n", inst0
>> 8, op
, reg
);
1423 inst0
|= 0x78000000 | (op
<< 24) | (reg
<< 16);
1425 else { /* A move to/from SFBR */
1426 if (reg
== 8) { /* MOVE SFBR <> TO reg */
1428 fprintf (listfp
, "Move SFBR to register: %02x %d %d\n", inst0
>> 8, op
, data
);
1430 inst0
|= 0x68000000 | (op
<< 24) | (data
<< 16);
1434 fprintf (listfp
, "Move register to SFBR: %02x %d %d\n", inst0
>> 8, op
, reg
);
1436 inst0
|= 0x70000000 | (op
<< 24) | (reg
<< 16);
1439 } else { /* register to register */
1440 data
= CheckRegister (tokenix
+2);
1442 errout ("Expected register");
1443 if (reg
== 8) /* move SFBR to reg */
1444 inst0
= 0x6a000000 | (data
<< 16);
1445 else if (data
== 8) /* move reg to SFBR */
1446 inst0
= 0x72000000 | (reg
<< 16);
1448 errout ("One register must be SFBR");
1452 void memory_to_memory ()
1454 inst0
= 0xc0000000 + evaluate (tokenix
+1);
1455 inst1
= evaluate (tokenix
+3);
1457 * need to hack dsps, otherwise patch offset will be wrong for
1461 inst2
= evaluate (tokenix
+5);
1467 if (errfp
!= listfp
&& errfp
&& err_listed
== 0) {
1468 fprintf (errfp
, "%3d: %s", lineno
, inbuf
);
1473 char * makefn (base
, sub
)
1479 fn
= malloc (strlen (base
) + strlen (sub
) + 2);
1481 base
= strrchr(fn
, '.');
1491 fprintf (stderr
, "usage: scc sourcfile [options]\n");