Annotation of sys/dev/microcode/siop/ncr53cxxx.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: ncr53cxxx.c,v 1.7 2005/10/08 15:54:49 krw Exp $ */
! 2: /* $NetBSD: ncr53cxxx.c,v 1.14 2005/02/11 06:21:22 simonb Exp $ */
! 3:
! 4: /*
! 5: * Copyright (c) 1995,1999 Michael L. Hitch
! 6: * All rights reserved.
! 7: *
! 8: * Redistribution and use in source and binary forms, with or without
! 9: * modification, are permitted provided that the following conditions
! 10: * are met:
! 11: * 1. Redistributions of source code must retain the above copyright
! 12: * notice, this list of conditions and the following disclaimer.
! 13: * 2. Redistributions in binary form must reproduce the above copyright
! 14: * notice, this list of conditions and the following disclaimer in the
! 15: * documentation and/or other materials provided with the distribution.
! 16: * 3. All advertising materials mentioning features or use of this software
! 17: * must display the following acknowledgement:
! 18: * This product includes software developed by Michael L. Hitch.
! 19: * 4. The name of the author may not be used to endorse or promote products
! 20: * derived from this software without specific prior written permission
! 21: *
! 22: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
! 23: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
! 24: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
! 25: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
! 26: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
! 27: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
! 28: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
! 29: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
! 30: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
! 31: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
! 32: */
! 33:
! 34: /* ncr53cxxx.c - SCSI SCRIPTS Assembler */
! 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); /* ENTRY, EXTERNAL label list */
! 59: void f_define (void); /* ABSOLUTE, RELATIVE label list */
! 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: * process options
! 351: * -l [listfile]
! 352: * -o [outputfile]
! 353: * -p [outputfile]
! 354: * -z [debugfile]
! 355: * -e [errorfile]
! 356: * -a arch
! 357: * -v
! 358: * -u
! 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: /* patches ? */
! 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: /* check for memory move instruction */
! 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; /* assume forward reference */
! 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: * f_list: process list of symbols for the ENTRY and EXTERNAL directive
! 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: * f_define: process list of definitions for ABSOLUTE and RELATIVE directive
! 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; /* Memory to memory move is 12 bytes */
! 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 /* driver will fix relative dsps to absolute */
! 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 /* driver will fix relative dsps to absolute */
! 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; /* ATN may be set from SELECT */
! 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 /* driver will fix relative dsps to absolute */
! 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; /*** ??? to match Zeus script */
! 1313: tokenix += 2;
! 1314: }
! 1315: else {
! 1316: inst0 |= evaluate (tokenix++); /* count */
! 1317: tokenix++; /* skip ',' */
! 1318: if (reserved ("ptr", tokenix)) {
! 1319: ++tokenix;
! 1320: inst0 |= 0x20000000;
! 1321: }
! 1322: inst1 = evaluate (tokenix++); /* address */
! 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: * MOVE reg/data8 TO reg register write
! 1341: * MOVE reg <op> data8 TO reg register write
! 1342: * MOVE reg + data8 TO reg WITH CARRY register write
! 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) { /* Not register, must be data */
! 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: /* A register read/write operator */
! 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) { /* A register read/modify/write */
! 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 { /* A move to/from SFBR */
! 1437: if (reg == 8) { /* MOVE SFBR <> TO reg */
! 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 { /* register to register */
! 1451: data = CheckRegister (tokenix+2);
! 1452: if (data < 0)
! 1453: errout ("Expected register");
! 1454: if (reg == 8) /* move SFBR to reg */
! 1455: inst0 = 0x6a000000 | (data << 16);
! 1456: else if (data == 8) /* move reg to SFBR */
! 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: * need to hack dsps, otherwise patch offset will be wrong for
! 1469: * second pointer
! 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: }
CVSweb