📄 ia64-gen.c
字号:
/* If it is a composite class, then ignore comments and notes that come after the '\\', since they don't apply to the part we are decoding now. */ if (xsect) { if (comment > xsect) comment = 0; if (notestr > xsect) notestr = 0; } if (notestr) { char *nextnotestr; note = atoi (notestr + 1); if ((nextnotestr = strchr (notestr + 1, '+')) != NULL) { if (strcmp (notestr, "+1+13") == 0) note = 13; else if (!xsect || nextnotestr < xsect) warn (_("multiple note %s not handled\n"), notestr); } } /* If it's a composite class, leave the notes and comments in place so that we have a unique name for the composite class. Otherwise, we remove them. */ if (!xsect) { if (notestr) *notestr = 0; if (comment) *comment = 0; } for (i = 0; i < iclen; i++) if (strcmp (name, ics[i]->name) == 0 && ((comment == NULL && ics[i]->comment == NULL) || (comment != NULL && ics[i]->comment != NULL && strncmp (ics[i]->comment, comment, strlen (ics[i]->comment)) == 0)) && note == ics[i]->note) return i; if (!create) return -1; /* Doesn't exist, so make a new one. */ if (iclen == ictotlen) { ictotlen += 20; ics = (struct iclass **) xrealloc (ics, (ictotlen) * sizeof (struct iclass *)); } ind = iclen++; ics[ind] = tmalloc (struct iclass); memset ((void *)ics[ind], 0, sizeof (struct iclass)); ics[ind]->name = xstrdup (name); ics[ind]->is_class = is_class; ics[ind]->orphan = 1; if (comment) { ics[ind]->comment = xstrdup (comment + 1); ics[ind]->comment[strlen (ics[ind]->comment)-1] = 0; } if (notestr) ics[ind]->note = note; /* If it's a composite class, there's a comment or note, look for an existing class or terminal with the same name. */ if ((xsect || comment || notestr) && is_class) { /* First, populate with the class we're based on. */ char *subname = name; if (xsect) *xsect = 0; else if (comment) *comment = 0; else if (notestr) *notestr = 0; ics[ind]->nsubs = 1; ics[ind]->subs = tmalloc(int); ics[ind]->subs[0] = fetch_insn_class (subname, 1);; } while (xsect) { char *subname = xsect + 1; xsect = strchr (subname, '\\'); if (xsect) *xsect = 0; ics[ind]->xsubs[ics[ind]->nxsubs] = fetch_insn_class (subname,1); ics[ind]->nxsubs++; } free (name); return ind;}/* 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 (void){ FILE *fp = fopen ("ia64-ic.tbl", "r"); char buf[2048]; if (fp == NULL) fail (_("can't find ia64-ic.tbl for reading\n")); /* 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) const 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) warn (_("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) fail (_("can't find %s for reading\n"), filename); 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 (void){ 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -