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 + -
显示快捷键?