📄 ia64-gen.c
字号:
return IA64_RS_PR; if (strstr (name, "PR%, % in 16 ") != NULL) return IA64_RS_PRr; warn (_("don't know how to specify %% dependency %s\n"), name); } else if (strchr (name, '#')) { if (strstr (name, "CPUID#") != NULL) return IA64_RS_CPUID; if (strstr (name, "DBR#") != NULL) return IA64_RS_DBR; if (strstr (name, "IBR#") != NULL) return IA64_RS_IBR; if (strstr (name, "MSR#") != NULL) return IA64_RS_MSR; if (strstr (name, "PKR#") != NULL) return IA64_RS_PKR; if (strstr (name, "PMC#") != NULL) return IA64_RS_PMC; if (strstr (name, "PMD#") != NULL) return IA64_RS_PMD; if (strstr (name, "RR#") != NULL) return IA64_RS_RR; warn (_("Don't know how to specify # dependency %s\n"), name); } else if (strncmp (name, "AR[FPSR]", 8) == 0) return IA64_RS_AR_FPSR; else if (strncmp (name, "AR[", 3) == 0) return IA64_RS_ARX; else if (strncmp (name, "CR[", 3) == 0) return IA64_RS_CRX; else if (strncmp (name, "PSR.", 4) == 0) return IA64_RS_PSR; else if (strcmp (name, "InService*") == 0) return IA64_RS_INSERVICE; else if (strcmp (name, "GR0") == 0) return IA64_RS_GR0; else if (strcmp (name, "CFM") == 0) return IA64_RS_CFM; else if (strcmp (name, "PR63") == 0) return IA64_RS_PR63; else if (strcmp (name, "RSE") == 0) return IA64_RS_RSE; return IA64_RS_ANY;}static voidprint_dependency_table (){ int i, j; if (debug) { for (i=0;i < iclen;i++) { if (ics[i]->is_class) { if (!ics[i]->nsubs) { if (ics[i]->comment) warn (_("IC:%s [%s] has no terminals or sub-classes\n"), ics[i]->name, ics[i]->comment); else warn (_("IC:%s has no terminals or sub-classes\n"), ics[i]->name); } } else { if (!ics[i]->terminal_resolved && !ics[i]->orphan) { if (ics[i]->comment) warn (_("no insns mapped directly to terminal IC %s [%s]"), ics[i]->name, ics[i]->comment); else warn (_("no insns mapped directly to terminal IC %s\n"), ics[i]->name); } } } for (i = 0; i < iclen; i++) { if (ics[i]->orphan) { mark_used (ics[i], 1); warn (_("class %s is defined but not used\n"), ics[i]->name); } } if (debug > 1) for (i = 0; i < rdepslen; i++) { static const char *mode_str[] = { "RAW", "WAW", "WAR" }; if (rdeps[i]->total_chks == 0) warn (_("Warning: rsrc %s (%s) has no chks%s\n"), rdeps[i]->name, mode_str[rdeps[i]->mode], rdeps[i]->total_regs ? "" : " or regs"); else if (rdeps[i]->total_regs == 0) warn (_("rsrc %s (%s) has no regs\n"), rdeps[i]->name, mode_str[rdeps[i]->mode]); } } /* The dependencies themselves. */ printf ("static const struct ia64_dependency\ndependencies[] = {\n"); for (i = 0; i < rdepslen; i++) { /* '%', '#', AR[], CR[], or PSR. indicates we need to specify the actual resource used. */ int specifier = lookup_specifier (rdeps[i]->name); int regindex = lookup_regindex (rdeps[i]->name, specifier); printf (" { \"%s\", %d, %d, %d, %d, ", rdeps[i]->name, specifier, (int)rdeps[i]->mode, (int)rdeps[i]->semantics, regindex); if (rdeps[i]->semantics == IA64_DVS_OTHER) { const char *quote, *rest; putchar ('\"'); rest = rdeps[i]->extra; quote = strchr (rest, '\"'); while (quote != NULL) { printf ("%.*s\\\"", (int) (quote - rest), rest); rest = quote + 1; quote = strchr (rest, '\"'); } printf ("%s\", ", rest); } else printf ("NULL, "); printf("},\n"); } printf ("};\n\n"); /* And dependency lists. */ for (i=0;i < dlistlen;i++) { int len = 2; printf ("static const unsigned short dep%d[] = {\n ", i); for (j=0;j < dlists[i]->len; j++) { len += printf ("%d, ", dlists[i]->deps[j]); if (len > 75) { printf("\n "); len = 2; } } printf ("\n};\n\n"); } /* And opcode dependency list. */ printf ("#define NELS(X) (sizeof(X)/sizeof(X[0]))\n"); printf ("static const struct ia64_opcode_dependency\n"); printf ("op_dependencies[] = {\n"); for (i = 0; i < opdeplen; i++) { printf (" { "); if (opdeps[i]->chk == -1) printf ("0, NULL, "); else printf ("NELS(dep%d), dep%d, ", opdeps[i]->chk, opdeps[i]->chk); if (opdeps[i]->reg == -1) printf ("0, NULL, "); else printf ("NELS(dep%d), dep%d, ", opdeps[i]->reg, opdeps[i]->reg); printf ("},\n"); } printf ("};\n\n");}/* Add STR to the string table. */static struct string_entry *insert_string (char *str){ int start = 0, end = strtablen; int i, x; if (strtablen == strtabtotlen) { strtabtotlen += 20; string_table = (struct string_entry **) xrealloc (string_table, sizeof (struct string_entry **) * strtabtotlen); } if (strtablen == 0) { strtablen = 1; string_table[0] = tmalloc (struct string_entry); string_table[0]->s = xstrdup (str); string_table[0]->num = 0; return string_table[0]; } if (strcmp (str, string_table[strtablen - 1]->s) > 0) i = end; else if (strcmp (str, string_table[0]->s) < 0) i = 0; else { while (1) { int c; i = (start + end) / 2; c = strcmp (str, string_table[i]->s); if (c < 0) end = i - 1; else if (c == 0) return string_table[i]; else start = i + 1; if (start > end) break; } } for (; i > 0 && i < strtablen; i--) if (strcmp (str, string_table[i - 1]->s) > 0) break; for (; i < strtablen; i++) if (strcmp (str, string_table[i]->s) < 0) break; for (x = strtablen - 1; x >= i; x--) { string_table[x + 1] = string_table[x]; string_table[x + 1]->num = x + 1; } string_table[i] = tmalloc (struct string_entry); string_table[i]->s = xstrdup (str); string_table[i]->num = i; strtablen++; return string_table[i];}static struct bittree *make_bittree_entry (void){ struct bittree *res = tmalloc (struct bittree); res->disent = NULL; res->bits[0] = NULL; res->bits[1] = NULL; res->bits[2] = NULL; res->skip_flag = 0; res->bits_to_skip = 0; return res;} static struct disent *add_dis_table_ent (which, insn, order, completer_index) struct disent *which; int insn; int order; int completer_index;{ int ci = 0; struct disent *ent; if (which != NULL) { ent = which; ent->nextcnt++; while (ent->nexte != NULL) ent = ent->nexte; ent = (ent->nexte = tmalloc (struct disent)); } else { ent = tmalloc (struct disent); ent->next_ent = disinsntable; disinsntable = ent; which = ent; } ent->nextcnt = 0; ent->nexte = NULL; ent->insn = insn; ent->priority = order; while (completer_index != 1) { ci = (ci << 1) | (completer_index & 1); completer_index >>= 1; } ent->completer_index = ci; return which;}static voidfinish_distable (){ struct disent *ent = disinsntable; struct disent *prev = ent; ent->ournum = 32768; while ((ent = ent->next_ent) != NULL) { ent->ournum = prev->ournum + prev->nextcnt + 1; prev = ent; }}static voidinsert_bit_table_ent (curr_ent, bit, opcode, mask, opcodenum, order, completer_index) struct bittree *curr_ent; int bit; ia64_insn opcode; ia64_insn mask; int opcodenum; int order; int completer_index;{ ia64_insn m; int b; struct bittree *next; if (bit == -1) { struct disent *nent = add_dis_table_ent (curr_ent->disent, opcodenum, order, completer_index); curr_ent->disent = nent; return; } m = ((ia64_insn) 1) << bit; if (mask & m) b = (opcode & m) ? 1 : 0; else b = 2; next = curr_ent->bits[b]; if (next == NULL) { next = make_bittree_entry (); curr_ent->bits[b] = next; } insert_bit_table_ent (next, bit - 1, opcode, mask, opcodenum, order, completer_index);}static voidadd_dis_entry (first, opcode, mask, opcodenum, ent, completer_index) struct bittree *first; ia64_insn opcode; ia64_insn mask; int opcodenum; struct completer_entry *ent; int completer_index;{ if (completer_index & (1 << 20)) abort (); while (ent != NULL) { ia64_insn newopcode = (opcode & (~ ent->mask)) | ent->bits; add_dis_entry (first, newopcode, mask, opcodenum, ent->addl_entries, (completer_index << 1) | 1); if (ent->is_terminal) { insert_bit_table_ent (bittree, 40, newopcode, mask, opcodenum, opcode_count - ent->order - 1, (completer_index << 1) | 1); } completer_index <<= 1; ent = ent->alternative; }}/* This optimization pass combines multiple "don't care" nodes. */static voidcompact_distree (ent) struct bittree *ent;{#define IS_SKIP(ent) \ ((ent->bits[2] !=NULL) \ && (ent->bits[0] == NULL && ent->bits[1] == NULL && ent->skip_flag == 0)) int bitcnt = 0; struct bittree *nent = ent; int x; while (IS_SKIP (nent)) { bitcnt++; nent = nent->bits[2]; } if (bitcnt) { struct bittree *next = ent->bits[2]; ent->bits[0] = nent->bits[0]; ent->bits[1] = nent->bits[1]; ent->bits[2] = nent->bits[2]; ent->disent = nent->disent; ent->skip_flag = 1; ent->bits_to_skip = bitcnt; while (next != nent) { struct bittree *b = next; next = next->bits[2]; free (b); } free (nent); } for (x = 0; x < 3; x++) { struct bittree *i = ent->bits[x]; if (i != NULL) compact_distree (i); }}static unsigned char *insn_list;static int insn_list_len = 0;static int tot_insn_list_len = 0;/* Generate the disassembler state machine corresponding to the tree in ENT. */static voidgen_dis_table (ent) struct bittree *ent;{ int x; int our_offset = insn_list_len; int bitsused = 5; int totbits = bitsused; int needed_bytes; int zero_count = 0; int zero_dest = 0; /* Initialize this with 0 to keep gcc quiet... */ /* If this is a terminal entry, there's no point in skipping any bits. */ if (ent->skip_flag && ent->bits[0] == NULL && ent->bits[1] == NULL && ent->bits[2] == NULL) { if (ent->disent == NULL) abort (); else ent->skip_flag = 0; } /* Calculate the amount of space needed for this entry, or at least a conservatively large approximation. */ if (ent->skip_flag) totbits += 5; for (x = 1; x < 3; x++) if (ent->bits[x] != NULL) totbits += 16; if (ent->disent != NULL) { if (ent->bits[2] != NULL) abort ();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -