📄 na.y
字号:
{ "gpreg", GPREG }, { "sfbr", SFBR }, { "socl", SOCL }, { "ssid", SSID }, { "sbcl", SBCL }, { "dstat", DSTAT }, { "sstat0", SSTAT0 }, { "sstat1", SSTAT1 }, { "sstat2", SSTAT2 }, { "dsa", DSA0 }, { "dsa0", DSA0 }, { "dsa1", DSA1 }, { "dsa2", DSA2 }, { "dsa3", DSA3 }, { "istat", ISTAT }, { "ctest0", CTEST0 }, { "ctest1", CTEST1 }, { "ctest2", CTEST2 }, { "ctest3", CTEST3 }, { "temp", TEMP }, { "dfifo", DFIFO }, { "ctest4", CTEST4 }, { "ctest5", CTEST5 }, { "ctest6", CTEST6 }, { "dbc", DBC }, { "dcmd", DCMD }, { "dnad", DNAD }, { "dsp", DSP }, { "dsps", DSPS }, { "scratcha", SCRATCHA0 }, { "scratcha0", SCRATCHA0 }, { "scratcha1", SCRATCHA1 }, { "scratcha2", SCRATCHA2 }, { "scratcha3", SCRATCHA3 }, { "dmode", DMODE }, { "dien", DIEN }, { "dwt", DWT }, { "dcntl", DCNTL }, { "adder", ADDER }, { "sien0", SIEN0 }, { "sien1", SIEN1 }, { "sist0", SIST0 }, { "sist1", SIST1 }, { "slpar", SLPAR }, { "macntl", MACNTL }, { "gpcntl", GPCNTL }, { "stime0", STIME0 }, { "stime1", STIME1 }, { "respid", RESPID }, { "stest0", STEST0 }, { "stest1", STEST1 }, { "stest2", STEST2 }, { "stest3", STEST3 }, { "sidl", SIDL }, { "sodl", SODL }, { "sbdl", SBDL }, { "scratchb", SCRATCHB0 }, { "scratchb0", SCRATCHB0 }, { "scratchb1", SCRATCHB1 }, { "scratchb2", SCRATCHB2 }, { "scratchb3", SCRATCHB3 }, { "scratchc", SCRATCHC0 }, { "scratchc0", SCRATCHC0 }, { "scratchc1", SCRATCHC1 }, { "scratchc2", SCRATCHC2 }, { "scratchc3", SCRATCHC3 }, { "add", ADD }, { "addc", ADDC }, { "and", AND }, { "or", OR }, { "xor", XOR }, { "shl", SHL }, { "shr", SHR }, { "jump", JUMP }, { "call", CALL }, { "return", RETURN }, { "int", INT }, { "intfly", INTFLY }, { "not", NOT }, { "absolute", ABSOLUTE }, { "mask", MASK }, { "if", IF }, { "rel", REL }, { "ptr", PTR }, { "table", TABLE }, { "from", FROM }, { "memory", MEMORY }, { "to", TO }, { "nop", NOP }, { "extern", EXTERN }, { "defw", DEFW },};#define TOKS (sizeof(toktab)/sizeof(toktab[0]))int lc;int ll;voidyyrewind(void){ rewind(in_f); ll = lc = 0; yyline = 0; dot = 0;}intyygetc(void){ if (lc == ll) { next: if (fgets(line, 500, in_f) == 0) return EOF; /* do nasty check for #line directives */ if (strncmp(line, "#line", 5) == 0) { /* #line n "filename" */ sscanf(line, "#line %d \"%[^\"]", &yyline, yyfilename); yyline--; goto next; } yyline++; ll = strlen(line); lc = 0; } return line[lc++];}voidyyungetc(void){ if (lc <= 0) exits("ungetc"); lc--;}intyylex(void){ char token[100]; int tl = 0; int c; while ((c = yygetc()) != EOF && (c == ' ' || c == '\t')) ; if (c == EOF) return 0; if (isalpha(c) || c == '_') { int x; do { token[tl++] = c; } while ((c = yygetc()) != EOF && (isalnum(c) || c == '_')); if (c == EOF) return 0; yyungetc(); token[tl] = 0; for (x = 0; x < TOKS; x++) if (strcmp(toktab[x].name, token) == 0) return toktab[x].tok; /* must be a symbol */ yylval.s = findsym(token); return SYMBOL; } else if (isdigit(c)) { /* accept 0x<digits> or 0b<digits> 0<digits> or <digits> */ int prefix = c == '0'; unsigned long n = c - '0'; int base = 10; for (;;) { c = yygetc(); if (c == EOF) return 0; if (prefix) { prefix = 0; if (c == 'x') { base = 16; continue; } else if (c == 'b') { base = 2; continue; } else base = 8; } if (isdigit(c)) c -= '0'; else if (isalpha(c) && base > 10) { if (isupper(c)) c = tolower(c); c = c - 'a' + 10; } else { yyungetc(); yylval.n = n; return NUM; } if (c >= base) yyerror("illegal format number"); n = n * base + c; } } else if (c == ';') { /* skip to end of line */ while ((c = yygetc()) != EOF && c != '\n') ; if (c != EOF) yyungetc(); return COMMENT; } return c;}voidyyerror(char *s, ...){ va_list ap; va_start(ap, s); fprintf(stderr, "%s: %d: ", yyfilename, yyline); vfprintf(stderr, s, ap); if (putc('\n', stderr) < 0) exits("io"); errors++; va_end(ap);}voidyywarn(char *s, ...){ va_list ap; va_start(ap, s); fprintf(stderr, "%s: %d: warning: ", yyfilename, yyline); vfprintf(stderr, s, ap); if (putc('\n', stderr) < 0) exits("io"); warnings++; va_end(ap);}voidp2error(int line, char *s){ USED(line); printf("/*\t%s */\n", s);}voidmain(int argc, char *argv[]){ int a; for (a = 1; a < argc; a++) { if (argv[a][0] == '-') switch (argv[a][1]) { case 'D': /* #defines for cpp */ if (ncppopts >= MAXCPPOPTS) { fprintf(stderr, "too many cpp options\n"); exits("options"); } cppopts[ncppopts++] = argv[a]; break; default: fprintf(stderr, "unrecognised option %s\n", argv[a]); exits("options"); } else break; } if (a != argc - 1) { fprintf(stderr, "usage: na [options] file\n"); exits("options"); } if (access(argv[a], 4) < 0) { fprintf(stderr, "can't read %s\n", argv[a]); exits(""); } in_f = tmpfile(); preprocess(argv[a], in_f); rewind(in_f); strcpy(yyfilename, argv[a]); yyparse(); if (errors) exits("pass1"); pass2 = 1; printf("unsigned long na_script[] = {\n"); yyrewind(); yyparse(); printf("};\n"); printf("\n"); printf("#define NA_SCRIPT_SIZE %d\n", dot / 4); printf("\n"); fixup();/* assemble();*/ exits(errors ? "pass2" : "");}voidpreprocess(char *in, FILE *out){ Waitmsg *w; char **argv; if (fork() == 0) { /* child */ dup(fileno(out), 1); argv = (char **)malloc(sizeof(char *) * (ncppopts + 5)); argv[0] = "cpp"; memcpy(&argv[1], cppopts, sizeof(char *) * ncppopts); argv[ncppopts + 1] = "-+"; argv[ncppopts + 2] = "-N"; argv[ncppopts + 3] = in; argv[ncppopts + 4] = 0; if (exec("/bin/cpp", argv) < 0) { fprintf(stderr, "failed to exec cpp (%R)\n"); exits("exec"); } exits(""); } w = wait(); free(w);}struct sym *findsym(char *name){ struct sym *s; for (s = symlist; s; s = s->next) if (strcmp(name, s->name) == 0) return s; s = (struct sym *)malloc(sizeof(*s)); s->name = strdup(name); s->t = Unknown; s->set = 0; s->next = symlist; symlist = s; return s;}voidsetsym(struct sym *s, Type t, long v){ if (pass2) { if (t == Unknown || t == Error) yyerror("can't resolve symbol"); else { s->t = t; s->value = v; } } else { if (s->set) yyerror("multiply defined symbol"); s->set = 1; s->t = t; s->value = v; }}intmk24bitssigned(long *l){ if (*l < 0) { if ((*l & 0xff800000L) != 0xff800000L) { *l = 0; return 0; } else *l = (*l) & 0xffffffL; } else if (*l > 0xffffffL) { *l = 0; return 0; } return 1;}static Type addresult[5][5] = {/* Const Addr Table Extern Reg *//* Const */ Const, Addr, Table, Error, Reg,/* Addr */ Addr, Error, Error, Error, Error,/* Table */ Table, Error, Error, Error, Error,/* Extern */ Error, Error, Error, Error, Error,/* Reg */ Reg, Error, Error, Error, Error,};static Type subresult[5][5] = {/* Const Addr Table Extern Reg *//* Const */ Const, Error, Error, Error, Error,/* Addr */ Addr, Const, Error, Error, Error,/* Table */ Table, Error, Const, Error, Error,/* Extern */ Error, Error, Error, Const, Error,/* Reg */ Error, Error, Error, Error, Error,};static Type muldivresult[5][5] = {/* Const Addr Table Extern *//* Const */ Const, Error, Error, Error, Error,/* Addr */ Error, Error, Error, Error, Error,/* Table */ Error, Error, Error, Error, Error,/* Extern */ Error, Error, Error, Error, Error,/* Reg */ Error, Error, Error, Error, Error,};static Type negresult[] = {/* Const */ Const,/* Addr */ Error,/* Table */ Error,/* Extern */ Error,/* Reg */ Error,};intpatchtype(Type t){ switch (t) { case Addr: return 1; case Reg: return 2; case Extern: return 4; default: return 0; }}struct expvaleval(struct expval a, struct expval b, char op){ struct expval c; if (a.t == Unknown || b.t == Unknown) { c.t = Unknown; c.value = 0; } else if (a.t == Error || b.t == Error) { c.t = Error; c.value = 0; } else { switch (op) { case '+': c.t = addresult[a.t][b.t]; break; case '-': c.t = subresult[a.t][b.t]; break; case '*': case '/': c.t = muldivresult[a.t][b.t]; break; case '_': case '~': c.t = negresult[a.t]; break; default: c.t = Error; break; } if (c.t == Error) { if (pass2) yyerror("type clash in evaluation"); c.value = 0; } else { switch (op) { case '+': c.value = a.value + b.value; break; case '-': c.value = a.value - b.value; break; case '*': c.value = a.value * b.value; break; case '/': c.value = a.value / b.value; break; case '_': c.value = -a.value; break; case '~': c.value = ~a.value; break; } } } return c;}voidregmove(unsigned char src_reg, unsigned char op, unsigned char dst_reg, struct expval *imm){ unsigned char func, reg; int immdata; out.len = 2; if (src_reg == 8) { func = 5; reg = dst_reg; } else if (dst_reg == 8) { func = 6; reg = src_reg; } else { if (pass2 && src_reg != dst_reg) yyerror("Registers must be the same"); func = 7; reg = src_reg; } immdata = imm ? (imm->value & 0xff) : 0; out.data[0] = 0x40000000L | ((long)func << 27) | ((long)op << 24) | ((long)reg << 16) | ((long)(immdata) << 8); out.data[1] = 0; out.patch[0] = (imm && imm->t == Extern) ? 3 : 0; out.patch[1] = 0;}longmkreladdr(long addr, int len){ long rel; rel = addr - (dot + 4 * len); mk24bitssigned(&rel); return rel;}longchkreladdr(int d, struct expval *e, int len, long relrv){ if (e->t == Addr) { out.data[d] = mkreladdr(e->value, len); out.patch[d] = 0; return relrv; } else { out.data[d] = e->value; out.patch[d] = patchtype(e->t); return 0; }}voidfixup(void){ struct sym *s; int p; printf("struct na_patch na_patches[] = {\n"); for (p = 0; p < patches; p++) { printf("\t{ 0x%.4x, %d }, /* %.8lx */\n", patch[p].lwoff, patch[p].type, patch[p].lwoff * 4L); } if (patches == 0) { printf("\t{ 0, 0 },\n"); } printf("};\n"); printf("#define NA_PATCHES %d\n", patches); printf("\n"); if (externs) { printf("enum na_external {\n"); for (p = 0; p < externs; p++) { printf("\tX_%s,\n", externp[p]->name); } printf("};\n"); } /* dump all labels (symbols of type Addr) as E_<Name> */ for (s = symlist; s; s = s->next) if (s->t == Addr) break; if (s) { printf("\nenum {\n"); while (s) { if (s->t == Addr) printf("\tE_%s = %ld,\n", s->name, s->value); s = s->next; } printf("};\n"); } /* dump all Consts as #define A_<Name> value */ for (s = symlist; s; s = s->next) if (s->t == Const) printf("#define A_%s %ld\n", s->name, s->value);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -