ia64-gen.c
来自「基于4个mips核的noc设计」· C语言 代码 · 共 2,504 行 · 第 1/5 页
C
2,504 行
}/* for sorting a class's sub-class list only; make sure classes appear before terminals */static intsub_compare (const void *e1, const void *e2){ struct iclass *ic1 = ics[*(int *)e1]; struct iclass *ic2 = ics[*(int *)e2]; if (ic1->is_class) { if (!ic2->is_class) return -1; } else if (ic2->is_class) return 1; return strcmp (ic1->name, ic2->name);}static voidload_insn_classes(){ FILE *fp = fopen("ia64-ic.tbl", "r"); char buf[2048]; if (fp == NULL){ fprintf (stderr, "Can't find ia64-ic.tbl for reading\n"); exit(1); } /* discard first line */ fgets (buf, sizeof(buf), fp); while (!feof(fp)) { int iclass; char *name; char *tmp; if (fgets (buf, sizeof(buf), fp) == NULL) break; while (isspace(buf[strlen(buf)-1])) buf[strlen(buf)-1] = '\0'; name = tmp = buf; while (*tmp != ';') { ++tmp; if (tmp == buf + sizeof(buf)) abort (); } *tmp++ = '\0'; iclass = fetch_insn_class(name, 1); ics[iclass]->is_class = 1; if (strcmp (name, "none") == 0) { ics[iclass]->is_class = 0; ics[iclass]->terminal_resolved = 1; continue; } /* for this class, record all sub-classes */ while (*tmp) { char *subname; int sub; while (*tmp && isspace(*tmp)) { ++tmp; if (tmp == buf + sizeof(buf)) abort(); } subname = tmp; while (*tmp && *tmp != ',') { ++tmp; if (tmp == buf + sizeof(buf)) abort(); } if (*tmp == ',') *tmp++ = '\0'; ics[iclass]->subs = (int *) xrealloc((void *)ics[iclass]->subs, (ics[iclass]->nsubs+1)*sizeof(int)); sub = fetch_insn_class(subname, 1); ics[iclass]->subs = (int *) xrealloc(ics[iclass]->subs, (ics[iclass]->nsubs+1)*sizeof(int)); ics[iclass]->subs[ics[iclass]->nsubs++] = sub; } /* make sure classes come before terminals */ qsort ((void *)ics[iclass]->subs, ics[iclass]->nsubs, sizeof(int), sub_compare); } fclose(fp); if (debug) { printf ("%d classes\n", iclen); }}/* extract the insn classes from the given line */static voidparse_resource_users(ref, usersp, nusersp, notesp) char *ref; int **usersp; int *nusersp; int **notesp;{ int c; char *line = xstrdup (ref); char *tmp = line; int *users = *usersp; int count = *nusersp; int *notes = *notesp; c = *tmp; while (c != 0) { char *notestr; int note; char *xsect; int iclass; int create = 0; char *name; while (isspace(*tmp)) ++tmp; name = tmp; while (*tmp && *tmp != ',') ++tmp; c = *tmp; *tmp++ = '\0'; xsect = strchr(name, '\\'); if ((notestr = strstr(name, "+")) != NULL) { char *nextnotestr; note = atoi (notestr + 1); if ((nextnotestr = strchr (notestr + 1, '+')) != NULL) { /* note 13 always implies note 1 */ if (strcmp (notestr, "+1+13") == 0) note = 13; else if (!xsect || nextnotestr < xsect) fprintf (stderr, "Warning: multiple note %s not handled\n", notestr); } if (!xsect) *notestr = '\0'; } else note = 0; /* All classes are created when the insn class table is parsed; Individual instructions might not appear until the dependency tables are read. Only create new classes if it's *not* an insn class, or if it's a composite class (which wouldn't necessarily be in the IC table). */ if (strncmp(name, "IC:", 3) != 0 || xsect != NULL) create = 1; iclass = fetch_insn_class(name, create); if (iclass != -1) { users = (int *) xrealloc ((void *)users,(count+1)*sizeof(int)); notes = (int *) xrealloc ((void *)notes,(count+1)*sizeof(int)); notes[count] = note; users[count++] = iclass; mark_used (ics[iclass], 0); } else { if (debug) printf("Class %s not found\n", name); } } /* update the return values */ *usersp = users; *nusersp = count; *notesp = notes; free (line);}static intparse_semantics (char *sem){ if (strcmp (sem, "none") == 0) return IA64_DVS_NONE; else if (strcmp (sem, "implied") == 0) return IA64_DVS_IMPLIED; else if (strcmp (sem, "impliedF") == 0) return IA64_DVS_IMPLIEDF; else if (strcmp (sem, "data") == 0) return IA64_DVS_DATA; else if (strcmp (sem, "instr") == 0) return IA64_DVS_INSTR; else if (strcmp (sem, "specific") == 0) return IA64_DVS_SPECIFIC; else if (strcmp (sem, "stop") == 0) return IA64_DVS_STOP; else return IA64_DVS_OTHER;}static voidadd_dep (const char *name, const char *chk, const char *reg, int semantics, int mode, char *extra, int flag){ struct rdep *rs; rs = insert_resource (name, mode); parse_resource_users (chk, &rs->chks, &rs->nchks, &rs->chknotes); parse_resource_users (reg, &rs->regs, &rs->nregs, &rs->regnotes); rs->semantics = semantics; rs->extra = extra; rs->waw_special = flag;}static voidload_depfile (const char *filename, enum ia64_dependency_mode mode){ FILE *fp = fopen(filename, "r"); char buf[1024]; if (fp == NULL){ fprintf (stderr, "Can't find %s for reading\n", filename); exit(1); } fgets(buf, sizeof(buf), fp); while (!feof(fp)) { char *name, *tmp; int semantics; char *extra; char *regp, *chkp; if (fgets (buf, sizeof(buf), fp) == NULL) break; while (isspace(buf[strlen(buf)-1])) buf[strlen(buf)-1] = '\0'; name = tmp = buf; while (*tmp != ';') ++tmp; *tmp++ = '\0'; while (isspace (*tmp)) ++tmp; regp = tmp; tmp = strchr (tmp, ';'); if (!tmp) abort (); *tmp++ = 0; while (isspace (*tmp)) ++tmp; chkp = tmp; tmp = strchr (tmp, ';'); if (!tmp) abort (); *tmp++ = 0; while (isspace (*tmp)) ++tmp; semantics = parse_semantics (tmp); extra = semantics == IA64_DVS_OTHER ? xstrdup (tmp) : NULL; /* For WAW entries, if the chks and regs differ, we need to enter the entries in both positions so that the tables will be parsed properly, without a lot of extra work */ if (mode == IA64_DV_WAW && strcmp (regp, chkp) != 0) { add_dep (name, chkp, regp, semantics, mode, extra, 0); add_dep (name, regp, chkp, semantics, mode, extra, 1); } else { add_dep (name, chkp, regp, semantics, mode, extra, 0); } } fclose(fp);}static voidload_dependencies(){ load_depfile ("ia64-raw.tbl", IA64_DV_RAW); load_depfile ("ia64-waw.tbl", IA64_DV_WAW); load_depfile ("ia64-war.tbl", IA64_DV_WAR); if (debug) printf ("%d RAW/WAW/WAR dependencies\n", rdepslen);}/* is the given operand an indirect register file operand? */static int irf_operand (int op, const char *field){ if (!field) { return op == IA64_OPND_RR_R3 || op == IA64_OPND_DBR_R3 || op == IA64_OPND_IBR_R3 || op == IA64_OPND_PKR_R3 || op == IA64_OPND_PMC_R3 || op == IA64_OPND_PMD_R3 || op == IA64_OPND_MSR_R3 || op == IA64_OPND_CPUID_R3; } else { return ((op == IA64_OPND_RR_R3 && strstr (field, "rr")) || (op == IA64_OPND_DBR_R3 && strstr (field, "dbr")) || (op == IA64_OPND_IBR_R3 && strstr (field, "ibr")) || (op == IA64_OPND_PKR_R3 && strstr (field, "pkr")) || (op == IA64_OPND_PMC_R3 && strstr (field, "pmc")) || (op == IA64_OPND_PMD_R3 && strstr (field, "pmd")) || (op == IA64_OPND_MSR_R3 && strstr (field, "msr")) || (op == IA64_OPND_CPUID_R3 && strstr (field, "cpuid"))); }}/* handle mov_ar, mov_br, mov_cr, mov_indirect, mov_ip, mov_pr, mov_psr, and mov_um insn classes */static intin_iclass_mov_x (struct ia64_opcode *idesc, struct iclass *ic, const char *format, const char *field){ int plain_mov = strcmp (idesc->name, "mov") == 0; if (!format) return 0; switch (ic->name[4]) { default: abort (); case 'a': { int i = strcmp (idesc->name, "mov.i") == 0; int m = strcmp (idesc->name, "mov.m") == 0; int i2627 = i && idesc->operands[0] == IA64_OPND_AR3; int i28 = i && idesc->operands[1] == IA64_OPND_AR3; int m2930 = m && idesc->operands[0] == IA64_OPND_AR3; int m31 = m && idesc->operands[1] == IA64_OPND_AR3; int pseudo0 = plain_mov && idesc->operands[1] == IA64_OPND_AR3; int pseudo1 = plain_mov && idesc->operands[0] == IA64_OPND_AR3; /* IC:mov ar */ if (i2627) return strstr (format, "I26") || strstr (format, "I27"); if (i28) return strstr (format, "I28") != NULL; if (m2930) return strstr (format, "M29") || strstr (format, "M30"); if (m31) return strstr (format, "M31") != NULL; if (pseudo0 || pseudo1) return 1; } break; case 'b': { int i21 = idesc->operands[0] == IA64_OPND_B1; int i22 = plain_mov && idesc->operands[1] == IA64_OPND_B2; if (i22) return strstr (format, "I22") != NULL; if (i21) return strstr (format, "I21") != NULL; } break; case 'c': { int m32 = plain_mov && idesc->operands[0] == IA64_OPND_CR3; int m33 = plain_mov && idesc->operands[1] == IA64_OPND_CR3; if (m32) return strstr (format, "M32") != NULL; if (m33) return strstr (format, "M33") != NULL; } break; case 'i': if (ic->name[5] == 'n') { int m42 = plain_mov && irf_operand (idesc->operands[0], field); int m43 = plain_mov && irf_operand (idesc->operands[1], field); if (m42) return strstr (format, "M42") != NULL; if (m43) return strstr (format, "M43") != NULL; } else if (ic->name[5] == 'p') { return idesc->operands[1] == IA64_OPND_IP; } else abort (); break; case 'p': if (ic->name[5] == 'r') { int i25 = plain_mov && idesc->operands[1] == IA64_OPND_PR; int i23 = plain_mov && idesc->operands[0] == IA64_OPND_PR; int i24 = plain_mov && idesc->operands[0] == IA64_OPND_PR_ROT; if (i23) return strstr (format, "I23") != NULL; if (i24) return strstr (format, "I24") != NULL; if (i25) return strstr (format, "I25") != NULL; } else if (ic->name[5] == 's') { int m35 = plain_mov && idesc->operands[0] == IA64_OPND_PSR_L; int m36 = plain_mov && idesc->operands[1] == IA64_OPND_PSR; if (m35) return strstr (format, "M35") != NULL; if (m36) return strstr (format, "M36") != NULL; } else abort (); break; case 'u': { int m35 = plain_mov && idesc->operands[0] == IA64_OPND_PSR_UM; int m36 = plain_mov && idesc->operands[1] == IA64_OPND_PSR_UM; if (m35) return strstr (format, "M35") != NULL; if (m36) return strstr (format, "M36") != NULL; } break; } return 0;}/* is the given opcode in the given insn class? */static intin_iclass(struct ia64_opcode *idesc, struct iclass *ic, const char *format, const char *field, int *notep){ int i; int resolved = 0; if (ic->comment) { if (!strncmp (ic->comment, "Format", 6)) { /* assume that the first format seen is the most restrictive, and only keep a later one if it looks like it's more restrictive. */ if (format) { if (strlen (ic->comment) < strlen (format)) { fprintf (stderr, "Warning: most recent format '%s'\n" "appears more restrictive than '%s'\n", ic->comment, format); format = ic->comment; } } else format = ic->comment; } else if (!strncmp (ic->comment, "Field", 5)) { if (field) fprintf (stderr, "Overlapping field %s->%s\n", ic->comment, field); field = ic->comment; } } /* an insn class matches anything that is the same followed by completers, except when the absence and presence of completers constitutes different instructions */ if (ic->nsubs == 0 && ic->nxsubs == 0) { int is_mov = strncmp (idesc->name, "mov", 3) == 0; int plain_mov = strcmp (idesc->name, "mov") == 0; int len = strlen(ic->name); resolved = ((strncmp (ic->name, idesc->name, len) == 0) && (idesc->name[len] == '\0' || idesc->name[len] == '.')); /* all break and nop variations must match exactly */ if (resolved && (strcmp (ic->name, "break") == 0
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?